Sql server 将数据插入存储过程中的不同表中
以下是始终插入表1的原始SP插入表1。现在,我需要插入到表1或表2中,它们都具有相同的结构 我试图将tableName作为参数传递到SPSql server 将数据插入存储过程中的不同表中,sql-server,tsql,stored-procedures,insert,sql-insert,Sql Server,Tsql,Stored Procedures,Insert,Sql Insert,以下是始终插入表1的原始SP插入表1。现在,我需要插入到表1或表2中,它们都具有相同的结构 我试图将tableName作为参数传递到SP ALTER PROCEDURE [dbo].[sp_importStats] ( @accountID BIGINT, @csvFileName VARCHAR (1024), @csvFormatFileName VARCHAR (1024) @tableName VARCHAR(256)) 然后我尝试使用EXECUTE插入,如下所示: --Incor
ALTER PROCEDURE [dbo].[sp_importStats] (
@accountID BIGINT,
@csvFileName VARCHAR (1024),
@csvFormatFileName VARCHAR (1024)
@tableName VARCHAR(256))
然后我尝试使用EXECUTE插入,如下所示:
--Incorrect syntax near EXECUTE.
EXECUTE(
'INSERT INTO '+ @tableName + '(accountId, date, cost)
(SELECT cte.id, ms.date, ms.cost
FROM #stats ms
INNER JOIN CTE cte ON ms.accountNumber = cte.key4)');
然后我试了一下:
--Must declare the table variable @tableName.
INSERT INTO @tableName (accountId, date, cost)
(SELECT cte.id, ms.date, ms.cost
FROM #stats ms
INNER JOIN CTE cte ON ms.accountNumber = cte.key4);
然后,我尝试不传递tableName,而是将布尔值传递到SP,并根据该值决定需要插入哪个表:
ALTER PROCEDURE [dbo].[sp_importStats] (
@accountID BIGINT,
@csvFileName VARCHAR (1024),
@csvFormatFileName VARCHAR (1024),
@condition BIT = 0)
IF (@condition= 0)
SET @table = 'table1'
ELSE
SET @table = 'table2'
--Must declare the table variable "@table".
INSERT INTO @table (accountId, date, cost)
(SELECT cte.id, ms.date, ms.cost
FROM #sats ms
INNER JOIN CTE cte ON ms.accountNumber = cte.key4);
不管怎样,我都有错误。你能告诉我处理这件事的最好方法吗?为什么我会收到这些错误?非常感谢您的帮助
原始SP:
ALTER PROCEDURE [dbo].[sp_importStats] (
@accountID BIGINT,
@csvFileName VARCHAR (1024),
@csvFormatFileName VARCHAR (1024))
AS
BEGIN
CREATE TABLE #stats(
[accountID] [bigint] NOT NULL,
[accountNumber] [varchar](30) NULL,
[date] [datetime] NOT NULL,
[cost] [money] NULL,
);
EXECUTE('INSERT INTO #stats SELECT * FROM '+
'OPENROWSET (BULK N''' + @csvFileName + '''' +
',FORMATFILE='''+@csvFormatFileName+''''+
',FIRSTROW=2'+
',MAXERRORS=0'+
') AS t;');
WITH CTE(id, key4) AS (
SELECT A.id, A.[key4]
FROM VA A (NOLOCK)
WHERE A.id = @accountID
UNION ALL
SELECT A.id, A.[key4]
FROM VA A (NOLOCK)
INNER JOIN CTE ON (CTE.id = A.MAID)
WHERE A.key4 IS NOT NULL
)
INSERT INTO table1 (accountId, date, cost)
(SELECT cte.id, ms.date, ms.cost
FROM #stats ms
INNER JOIN CTE cte ON ms.accountNumber = cte.key4);
DROP TABLE #stats;
END
这就是我现在拥有的:
ALTER PROCEDURE [dbo].[sp_importStats] (
@accountID BIGINT,
@csvFileName VARCHAR (1024),
@csvFormatFileName VARCHAR (1024)
@tableName VARCHAR(256))
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
CREATE TABLE #stats(
[accountID] [bigint] NOT NULL,
[accountNumber] [varchar](30) NULL,
[date] [datetime] NOT NULL,
[cost] [money] NULL,
);
EXECUTE('INSERT INTO #stats SELECT * FROM '+
'OPENROWSET (BULK N''' + @csvFileName + '''' +
',FORMATFILE='''+@csvFormatFileName+''''+
',FIRSTROW=2'+
',MAXERRORS=0'+
') AS t;');
WITH CTE(id, key4) AS (
SELECT A.id, A.[key4]
FROM VA A (NOLOCK)
WHERE A.id = @accountID
UNION ALL
SELECT A.id, A.[key4]
FROM VA A (NOLOCK)
INNER JOIN CTE ON (CTE.id = A.MAID)
WHERE A.key4 IS NOT NULL
)
--Incorect synstax near SET.
SET @sql = 'INSERT INTO '+ QUOTENAME(@tableName) + '(accountId, date, cost)
(SELECT cte.id, ms.date, ms.cost
FROM #stats ms
INNER JOIN CTE cte ON ms.accountNumber = cte.key4)';
EXECUTE sp_executesql @sql;
DROP TABLE #stats;
END
将表名作为参数传递
使用QUOTENAME函数在表名周围放上方括号,以明确地告诉sql server它是一个sql server对象名,如下所示
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N';WITH CTE(id, key4) AS (
SELECT A.id, A.[key4]
FROM VA A (NOLOCK)
WHERE A.id = @accountID
UNION ALL
SELECT A.id, A.[key4]
FROM VA A (NOLOCK)
INNER JOIN CTE ON (CTE.id = A.MAID)
WHERE A.key4 IS NOT NULL
)
INSERT INTO ' + QUOTENAME(@tableName) +' (accountId, date, cost)
SELECT cte.id, ms.date, ms.cost
FROM #stats ms
INNER JOIN CTE cte ON ms.accountNumber = cte.key4;'
EXECUTE sp_executesql @Sql
使用QUOTENAME函数可以防止可能的sql注入攻击。此外,select语句周围不需要括号
此外,还应避免在存储过程名称中使用sp_uu前缀。为什么
使用IF..ELSE块
您是否注意到声明中遗漏了一个逗号
ALTER PROCEDURE [dbo].[sp_importStats] (
@accountID BIGINT,
@csvFileName VARCHAR (1024),
@csvFormatFileName VARCHAR (1024),---comma missing here
@tableName VARCHAR(256))
我得到:集合附近的非直联。这是我之前定义的b/c CTE吗?@blueSky update your question show确切地显示了你在做什么?用你的建议用SP更新了我的帖子。如果尝试第二种解决方案,我还发现“IF”附近的语法不正确。@blueSky抱歉,我没有意识到你在从CTE插入值,这个CTE需要放在你的动态sql语句中,看一看,我已经更新了我的答案
ALTER PROCEDURE [dbo].[sp_importStats] (
@accountID BIGINT,
@csvFileName VARCHAR (1024),
@csvFormatFileName VARCHAR (1024),---comma missing here
@tableName VARCHAR(256))