【问题标题】:Writing dynamic SQL in SQL Server 2016 throwing error在 SQL Server 2016 中编写动态 SQL 抛出错误
【发布时间】:2021-03-28 04:11:11
【问题描述】:

这是我在 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]

请帮忙。

【问题讨论】:

  • 也许你可以在这里找到答案?已经回答了很多,快速谷歌会给出很多结果。 stackoverflow.com/questions/35505282/…
  • 这里与您的问题无关,但您为什么要删除并创建表格?为什么不使用MERGEINSERT & UPDATE

标签: sql-server tsql dynamic-sql


【解决方案1】:

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

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;

【讨论】:

    【解决方案2】:

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

    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 中引用的表与INTO 相同。
    • 将常量值作为参数传递。

    【讨论】:

      猜你喜欢
      • 2011-04-01
      • 1970-01-01
      • 2020-03-31
      • 2023-03-15
      • 1970-01-01
      • 2019-10-23
      • 2016-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多