在 SQL Server 2016 中写入动态 SQL 抛出错误

Writing dynamic SQL in SQL Server 2016 throwing error

这是我在 SQL Server 2016 中的存储过程:

CREATE PROCEDURE [USA_PHILIPS].[usp_stock]
    @VCM INT,
    @ID VARCHAR, 
    @SCHEMA_NAME VARCHAR(50)
AS
BEGIN
    SET NOCOUNT ON;

    DROP TABLE IF EXISTS [USA_PHILIPS].[stock]

    SELECT STOCKNUMBER,STOCKBOOKS
    INTO [USA_PHILIPS].[stock]
    FROM [USA_PHILIPS].[DMARTSTOCK]
    WHERE VCM = @VCM
      AND ID = @ID
END

如何将架构名称作为参数传递@SCHEMA_NAME

并以动态方式执行这些语句 SQL:

DROP TABLE IF EXISTS [USA_PHILIPS].[stock]

请帮忙。

如果标识符是动态的,则所有代码都必须是动态的——并且您必须修改查询字符串:

CREATE PROCEDURE [USA_PHILIPS].[usp_stock] (
    @VCM INT,
    @ID VARCHAR(255), 
    @SCHEMA_NAME VARCHAR(50)
) AS
BEGIN

    DECLARE @sql = NVARCHAR(MAX);
    SET @sql = 'DROP TABLE IF EXISTS [SCHEMA].[stock]';
    SET @sql = REPLACE(@sql, '[SCHEMA]', QUOTENAME(@SCHEMA_NAME));

    EXEC sp_executeSQL @sql;

    SET @sql = '
SELECT STOCKNUMBER, STOCKBOOKS
Into [SCHEMA].[stock]
from [USA_PHILIPS].[DMARTSTOCK]
WHERE VCM=@VCM AND ID = @ID';

    SET @sql = REPLACE(@sql, '[SCHEMA]', QUOTENAME(@SCHEMA_NAME));

    EXEC sp_executesql @sql,
         N'@vcm INT, @id VARCHAR(255)',
         @vcm=@vcm, @id=@id;

END;

注意查询的一些重要变化:

  • @ID 有一个长度作为参数。这很重要,因为默认值因上下文而异,并且它可能(很可能还不够)足以满足您的需求。
  • 我假设您希望 DELETE 中引用的 table 与 INTO 中引用的相同 table。
  • 将常量值作为参数传递。

我个人会这样做,将指向的值注入到动态查询中。我还修复了您的一些数据类型:

CREATE PROCEDURE [USA_PHILIPS].[usp_stock] @VCM int,
                                           @ID varchar(25), --Always define your varchar lengths
                                           @SCHEMA_NAME sysname --Correct data type for object names

AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @SQL nvarchar(MAX),
            @CRLF nchar(2) = NCHAR(13) + NCHAR(10)
   
    SET @SQL = N'DROP TABLE IF EXISTS ' + QUOTENAME(@SCHEMA_NAME) + N'.[stock];' + @CRLF + @CRLF +
               N'SELECT STOCKNUMBER,STOCKBOOKS' + @CRLF +
               N'INTO ' + QUOTEMANE(@SCHEMA_NAME) + N'.[stock]' + @CRLF +
               N'FROM [USA_PHILIPS].[DMARTSTOCK]' + @CRLF +
               N'WHERE VCM=@VCM' + @CRLF +
               N'  AND ID = @ID;';

    EXEC sys.sp_executesql @SQL, N'@VCM int, @ID varchar(25)', @VCM, @ID;

END;