SQL Server:存储过程不起作用,但在存储过程之外起作用

时间:2020-03-14 10:09:09

标签: sql-server stored-procedures

SQL Server:以下存储过程不起作用,但是SQL语句在存储过程之外起作用。

CREATE PROCEDURE schema1.dropConstraints
      (@schemaName AS nvarchar, @tableName AS nvarchar) 
AS
BEGIN
    DECLARE @cname nvarchar(80)
    DECLARE @sqlStatement nvarchar(100)

    DECLARE myCursor CURSOR LOCAL FOR
        SELECT constraint_name 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
        WHERE constraint_schema = @schemaName 
          AND table_name = @tableName;

    OPEN myCursor;
    FETCH NEXT FROM myCursor INTO @cname;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @sqlStatement = 'ALTER TABLE ' + @schemaName + '.' + @tableName + ' DROP CONSTRAINT ' + @cname;
        EXEC sp_executesql @sqlStatement;

        FETCH NEXT FROM myCursor INTO @cname;
    END;

    CLOSE myCursor;
    DEALLOCATE myCursor;
END;

调用存储过程

exec schema1.dropConstraints 'schema1', 'Foo';

Foo的约束(PK,FK)未删除。没有错误。

但是在存储过程之外运行代码,效果很好。

    DECLARE @schemaName nvarchar(80) = 'schema1';
    DECLARE @tableName nvarchar(80) = 'Foo';

    DECLARE @cname nvarchar(80)
    DECLARE @sqlStatement nvarchar(100)

    DECLARE myCursor CURSOR LOCAL FOR 
        SELECT constraint_name 
        FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
        WHERE constraint_schema = @schemaName AND table_name = @tableName;

    OPEN myCursor;
    FETCH NEXT FROM myCursor INTO @cname;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @sqlStatement = 'ALTER TABLE ' + @schemaName + '.' + @tableName + ' DROP CONSTRAINT ' + @cname;
        EXEC sp_executesql @sqlStatement;

        FETCH NEXT FROM myCursor INTO @cname;
    END;

    CLOSE myCursor;
    DEALLOCATE myCursor;

这有效。表Foo的约束(PK,FK)已删除。有什么区别?

登录:sa。

1 个答案:

答案 0 :(得分:2)

这些参数数据类型声明中缺少最大字符长度:

CREATE PROCEDURE schema1.dropConstraints
      (@schemaName AS nvarchar, @tableName AS nvarchar) 

因为默认长度为1,所以提供的值将被静默截断为单个字符,并且结果与预期不符。

确保参数数据类型和长度与引用列的类型匹配是一种很好的做法。对于INFORMATION_SCHEMA视图,请查阅documentation,您会发现适当的数据类型为nvarchar(128)。我个人喜欢在SQL Server中将sysname用于标识符类型,这是nvarchar(128)的同义词。

CREATE PROCEDURE schema1.dropConstraints
      @schemaName AS sysname, @tableName AS sysname
相关问题