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 搜索将在找到满足条件的单个记录后立即停止)。