如何以文本形式指示sql select中没有结果?

7cwmlq89  于 2021-07-24  发布在  Java
关注(0)|答案(8)|浏览(390)

我有以下sql CASE 语句似乎没有正确计算条件。这个表当前是空的(0个非空行),所以我假设 ELSE 条件应为true,因此输出下面的文本字符串。但是,它不会填充结果中的任何内容。

SELECT 
CASE WHEN EC.INV_ITEM_ID <> '' THEN EC.INV_ITEM_ID
     ELSE 'NO ITEMS IN STAGING TABLES'
     END

FROM PS_MASTER_ITEM_EC EC
ORDER BY INV_ITEM_ID
h22fl7wq

h22fl7wq1#

IF ((SELECT COUNT(*) FROM PS_MASTER_ITEM_EC EC WHERE EC.INV_ITEM_ID <> '' AND EC.INV_ITEM_ID IS NOT NULL) > 0)
SELECT EC.INV_ITEM_ID FROM PS_MASTER_ITEM_EC EC WHERE EC.INV_ITEM_ID <> '' AND EC.INV_ITEM_ID IS NOT NULL
ELSE
SELECT 'NO ITEMS IN STAGING TABLES'

第一行将计算表中有多少非空行第二行将返回一个1列的表,其中所有ID都不是null,如果在所有第四行中都找到任何ID,则第四行将返回默认消息(如果该表实际上是空的)

ego6inou

ego6inou2#

不能从空表返回记录。case语句将根据表中的每条记录进行求值。当没有记录时,就没有什么可计算的,因此结果集是空的。有几种方法可以检查这种情况。如果客户机需要一个特定的结果集,并且会检查一个已知的字段是否存在数据(这似乎有点不正常),那么您可以通过消息传递从派生的结果集中返回类似形状的数据,我鼓励您考虑在消费者处检查这种情况,因为数据库查询更适合于插入/更新/删除和获取数据。

DECLARE @PS_MASTER_ITEM_EC TABLE(INV_ITEM_ID NVARCHAR(200))
--INSERT @PS_MASTER_ITEM_EC VALUES ('I''m Here')

IF(NOT EXISTS(SELECT EC.INV_ITEM_ID FROM @PS_MASTER_ITEM_EC EC))
    SELECT INV_ITEM_ID =  'NO ITEMS IN STAGING TABLES'
ELSE
SELECT 
CASE WHEN EC.INV_ITEM_ID <> '' THEN EC.INV_ITEM_ID
     ELSE 'EC.INV_ITEM_ID has an empty string for a value'
     END AS INV_ITEM_ID

FROM @PS_MASTER_ITEM_EC EC
ORDER BY INV_ITEM_ID
vaj7vani

vaj7vani3#

你的问题是 CASE 仅对现有行求值,如果表为空,则根本不会得到任何记录。
但是,即使表为空,您也希望获得包含消息的记录,因此必须创建该行。你可以用 UNION 仅在下列情况下向结果集中添加新行 PS_MASTER_ITEM_EC 是空的。
因此,您可以简单地列出所有记录(如果有的话),并在需要时显示您的消息 PS_MASTER_ITEM_EC 是空的。

SELECT EC.INV_ITEM_ID
FROM PS_MASTER_ITEM_EC EC
ORDER BY INV_ITEM_ID

UNION ALL

SELECT 'NO ITEMS IN STAGING TABLES'
WHERE NOT EXISTS(SELECT TOP 1 'X' X FROM PS_MASTER_ITEM_EC )

注意,你需要 INV_ITEM_ID 列的类型为char/varchar/nvarchar,否则将出现错误。如果你的 INV_ITEM_ID 是可以使用此解决方法的数字:

SELECT EC.INV_ITEM_ID, NULL Message
FROM PS_MASTER_ITEM_EC EC
ORDER BY INV_ITEM_ID

UNION ALL

SELECT NULL INV_ITEM_ID, 'NO ITEMS IN STAGING TABLES' Message
WHERE NOT EXISTS(SELECT TOP 1 'X' X FROM PS_MASTER_ITEM_EC )
8dtrkrch

8dtrkrch4#

sql server是一个 relational 数据库。关系数据库是关闭的 sets ,基本上是一个记录列表。如果没有记录,那么您的函数/逻辑( CASE 在这种情况下)不能应用。如果您需要在查询返回零记录时返回一个记录,那么您需要提供一个来自另一个要返回的源的记录。一种方法是通过 UNION 用一个 WHERE 子句,该子句保证在结果集为空时返回特殊记录。当结果集不为空时,则 WHERE 子句确保不返回此新记录。这里的问题是,这个特殊记录必须与常规查询结果具有相同的列数,并且具有相同或兼容的数据类型。

; WITH cte (
 ---- your complex query goes here 
  select colString, colNumeric 
   .............
) 
SELECT colString, colNumeric FROM cte 
UNION ALL
SELECT 'no result found' as colString, NULL as colNumeric  WHERE NOT EXISTS (SELECT * FROM cte) --- this returns true only if no record in cte
mwyxok5s

mwyxok5s5#

使用公共表表达式(cte),一个用于主查询(您的查询),另一个用于检查您感兴趣的表是否为空。

WITH MainQuery AS (
  SELECT 
  CASE WHEN EC.INV_ITEM_ID <> '' THEN EC.INV_ITEM_ID
       END AS INV_ITEM_ID
  FROM PS_MASTER_ITEM_EC EC
),
EmptyTableMessage AS (
  SELECT
  CASE WHEN (SELECT COUNT(*) FROM MainQuery) > 0 THEN ''
       ELSE 'NO ITEMS IN STAGING TABLES'
       END AS EmptyMessage 
)
SELECT
EmptyTableMessage.EmptyMessage,
MainQuery.*
FROM EmptyTableMessage
LEFT OUTER JOIN MainQuery ON 1 = 1
ORDER BY MainQuery.INV_ITEM_ID

可以随意更改 MainQuery 任何你需要的查询并更改 ORDER BY 根据合同的内容在最后加上条款 MainQuery .
这样做的负面影响是,您总是会有一个额外的列,其中包含空表/记录/结果的消息(作为占位符)。

8cdiaqws

8cdiaqws6#

列中的所有值必须具有相同的数据类型。所以如果 INV_ITEM_ID 列正用于字符串值 'NO ITEMS IN STAGING TABLES' 如果没有任何记录,则列必须具有文本数据类型。
如果不是这样,您需要将id转换为字符串,以便在有记录的情况下与之匹配。就我个人而言,我建议不要这样做,因为这就像粉笔和奶酪的混合——字符串值实际上不属于数字id列——而且即使id碰巧是字符串,它仍然值得怀疑,因为从语义上讲,“no results”字符串不是id。
但如果您真的想这样做,可以使用以下sql实现:

SELECT 'NO ITEMS IN STAGING TABLES' AS INV_ITEM_ID
WHERE NOT EXISTS (SELECT * FROM PS_MASTER_ITEM_EC)
UNION ALL 
SELECT CAST(INV_ITEM_ID AS VARCHAR(26))
FROM PS_MASTER_ITEM_EC EC
ORDER BY INV_ITEM_ID;

雷克斯测试仪demo:httpshttp://rextester.com/firwf53864

djp7away

djp7away7#

它可以通过使用 LEFT JOIN :

SELECT IIF(EC.INV_ITEM_ID <> '', EC.INV_ITEM_ID, s.col)
FROM (SELECT 'NO ITEMS IN STAGING TABLES') s(col)
LEFT JOIN PS_MASTER_ITEM_EC EC ON 1=1
ORDER BY EC.INV_ITEM_ID;

db<>小提琴演示
情节:

CREATE TABLE PS_MASTER_ITEM_EC(INV_ITEM_ID NVARCHAR(10));

-- case 1: empty value
INSERT INTO PS_MASTER_ITEM_EC VALUES ('');
-- NO ITEMS IN STAGING TABLES

-- case 2: empty table
TRUNCATE TABLE PS_MASTER_ITEM_EC
-- NO ITEMS IN STAGING TABLES

-- case 3: data in table
INSERT INTO PS_MASTER_ITEM_EC VALUES ('abc')
-- output: abc
jdzmm42g

jdzmm42g8#

如果你的问题只是为什么没有结果,我的回答是:
sql查询由称为“子句”的不同部分组成。 SELECT 以及 FROM 是其中的两个(可能是最重要的)。
不管你在报纸上写什么 SELECT 条款(即 SELECT 在那之前 FROM )只能从中写入的结果行生成列 FROM 条款。table PS_MASTER_ITEM_EC 在你的 FROM 子句不包含任何行,因此 FROM 子句不能生成任何行。因此 SELECT 子句没有任何可以为其创建列的行。
但是有一个例外:如果你忽略了 FROM 条款, SELECT 可以用一行生成结果,如中所示

SELECT 'no result found' as Dummy
-- Will generate a result with one row, one column "Dummy" containing 'no result found'

相关问题