SQL动态查询:检查table列是否有数据
SQL dynamic query: check whether table column has any data
我确实有动态生成的 tables 列表,用户可以修改那些 tables 例如:添加列和删除列,添加数据等。
我需要修改这个存储过程,当用户需要从特定的table中删除特定的列时,我需要首先检查列是否有数据,如果没有数据用户可以更改table .为了达到这个条件,我写了代码但它不起作用:
DROP TABLE IF EXISTS #TABLEDATACOUNT
CREATE TABLE #TABLEDATACOUNT(C BIGINT)
DECLARE @dataCountQuery NVARCHAR(MAX)='SELECT COUNT(*) AS C FROM ['+@DynamicTable+']'
INSERT INTO #TABLEDATACOUNT
EXEC sys.sp_executesql @dataCountQuery
IF EXISTS (SELECT * FROM #TABLEDATACOUNT WHERE C>0)
BEGIN
INSERT INTO @RESULT (ID, [MESSAGE])
VALUES (1, 'Data exists!')
-- INSERTING NEW COLUMNS
IF(LEN(@fields) = 0)
GOTO EXITSP
DECLARE @index1 BIGINT = 0
WHILE(@index1 < (SELECT COUNT(*) FROM OPENJSON(@fields)))
BEGIN
DECLARE @fieldJson1 NVARCHAR(MAX)=(SELECT [VALUE] FROM OPENJSON(@fields) WHERE [KEY]=@index1)
DECLARE @fieldName1 NVARCHAR(MAX)=(SELECT [VALUE] FROM OPENJSON(@fieldJson1) WHERE [KEY]='name')
DECLARE @fieldType1 NVARCHAR(MAX)=(SELECT [VALUE] FROM OPENJSON(@fieldJson1) WHERE [KEY]='type')
IF((SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=+'['+@DynamicTable+'] AND COLUMN_NAME='+@fieldName1)=0)
BEGIN
DECLARE @insertSql NVARCHAR(MAX)=('ALTER TABLE ['+@DynamicTable+'] ADD ['+@fieldName1+'] '+@fieldType1)
EXEC sys.sp_executesql @insertSql
INSERT INTO @RESULT (ID,[MESSAGE]) VALUES (3,'Column inserted')
END
IF((SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=+'['+@DynamicTable+'] AND COLUMN_NAME='+@fieldName1)=1)
BEGIN
-- Here I need Your support
-- If Block CHECK table field has no data then user can drop the column
IF((N'SELECT MAX(['+@fieldName1+']) FROM ['+@dynamicTableName+']')= 'NULL')
DECLARE @dropfieldSql NVARCHAR(MAX)=('ALTER TABLE ['+@DynamicTable+'] DROP COLUMN ['+@fieldName1+'])
EXEC sys.sp_executesql @dropfieldSql
--INSERT INTO @RESULT (ID,[MESSAGE]) VALUES (3,'Column inserted')
END
SET @index1=@index1+1
END
END
ELSE
-- This I managed
在上面的代码中
我需要你的支持
-- If Block CHECK table field has no data then user can drop the column
IF((N'SELECT MAX(['+@fieldName1+']) FROM ['+@dynamicTableName+']')= 'NULL')
您没有执行测试。你需要这样的东西:
declare @rowcheck int = 0;
declare @rowchecksql nvarchar(1000) = N'SELECT @rows=1 WHERE EXISTS (SELECT ['+@fieldName1+'] FROM ['+@dynamicTableName+'] WHERE ['+@fieldName1+'] IS NOT NULL);';
exec sp_executesql @rowchecksql, N'@rows INT OUTPUT', @rows=@rowcheck OUTPUT;
然后你可以继续:
IF @rowcheck = 0
BEGIN
...;
END
请注意,我们必须为动态 sql 创建一个 OUTPUT
参数,然后将此参数分配给我们已经声明的变量。那么当我们执行动态sql的时候,这个变量就被赋值了,然后我们就可以检查它了。另请注意,此处 COUNT 优于 MAX。
编辑:感谢@Charlieface 指出 EXISTS 更好(因为 table 搜索将在找到满足条件的单个记录后立即停止)。
我确实有动态生成的 tables 列表,用户可以修改那些 tables 例如:添加列和删除列,添加数据等。
我需要修改这个存储过程,当用户需要从特定的table中删除特定的列时,我需要首先检查列是否有数据,如果没有数据用户可以更改table .为了达到这个条件,我写了代码但它不起作用:
DROP TABLE IF EXISTS #TABLEDATACOUNT
CREATE TABLE #TABLEDATACOUNT(C BIGINT)
DECLARE @dataCountQuery NVARCHAR(MAX)='SELECT COUNT(*) AS C FROM ['+@DynamicTable+']'
INSERT INTO #TABLEDATACOUNT
EXEC sys.sp_executesql @dataCountQuery
IF EXISTS (SELECT * FROM #TABLEDATACOUNT WHERE C>0)
BEGIN
INSERT INTO @RESULT (ID, [MESSAGE])
VALUES (1, 'Data exists!')
-- INSERTING NEW COLUMNS
IF(LEN(@fields) = 0)
GOTO EXITSP
DECLARE @index1 BIGINT = 0
WHILE(@index1 < (SELECT COUNT(*) FROM OPENJSON(@fields)))
BEGIN
DECLARE @fieldJson1 NVARCHAR(MAX)=(SELECT [VALUE] FROM OPENJSON(@fields) WHERE [KEY]=@index1)
DECLARE @fieldName1 NVARCHAR(MAX)=(SELECT [VALUE] FROM OPENJSON(@fieldJson1) WHERE [KEY]='name')
DECLARE @fieldType1 NVARCHAR(MAX)=(SELECT [VALUE] FROM OPENJSON(@fieldJson1) WHERE [KEY]='type')
IF((SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=+'['+@DynamicTable+'] AND COLUMN_NAME='+@fieldName1)=0)
BEGIN
DECLARE @insertSql NVARCHAR(MAX)=('ALTER TABLE ['+@DynamicTable+'] ADD ['+@fieldName1+'] '+@fieldType1)
EXEC sys.sp_executesql @insertSql
INSERT INTO @RESULT (ID,[MESSAGE]) VALUES (3,'Column inserted')
END
IF((SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=+'['+@DynamicTable+'] AND COLUMN_NAME='+@fieldName1)=1)
BEGIN
-- Here I need Your support
-- If Block CHECK table field has no data then user can drop the column
IF((N'SELECT MAX(['+@fieldName1+']) FROM ['+@dynamicTableName+']')= 'NULL')
DECLARE @dropfieldSql NVARCHAR(MAX)=('ALTER TABLE ['+@DynamicTable+'] DROP COLUMN ['+@fieldName1+'])
EXEC sys.sp_executesql @dropfieldSql
--INSERT INTO @RESULT (ID,[MESSAGE]) VALUES (3,'Column inserted')
END
SET @index1=@index1+1
END
END
ELSE
-- This I managed
在上面的代码中
我需要你的支持
-- If Block CHECK table field has no data then user can drop the column
IF((N'SELECT MAX(['+@fieldName1+']) FROM ['+@dynamicTableName+']')= 'NULL')
您没有执行测试。你需要这样的东西:
declare @rowcheck int = 0;
declare @rowchecksql nvarchar(1000) = N'SELECT @rows=1 WHERE EXISTS (SELECT ['+@fieldName1+'] FROM ['+@dynamicTableName+'] WHERE ['+@fieldName1+'] IS NOT NULL);';
exec sp_executesql @rowchecksql, N'@rows INT OUTPUT', @rows=@rowcheck OUTPUT;
然后你可以继续:
IF @rowcheck = 0
BEGIN
...;
END
请注意,我们必须为动态 sql 创建一个 OUTPUT
参数,然后将此参数分配给我们已经声明的变量。那么当我们执行动态sql的时候,这个变量就被赋值了,然后我们就可以检查它了。另请注意,此处 COUNT 优于 MAX。
编辑:感谢@Charlieface 指出 EXISTS 更好(因为 table 搜索将在找到满足条件的单个记录后立即停止)。