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