Sql server 将数据插入存储过程中的不同表中

Sql 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

以下是始终插入表1的原始SP插入表1。现在,我需要插入到表1或表2中,它们都具有相同的结构

我试图将tableName作为参数传递到SP

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))