尽管有几种 SQL 方言可以,但 SQL Server 不支持将变量作为对象名称。您必须使用动态 SQL 来解决这个问题。
注释掉这些EXEC行并取消注释这些PRINT行以验证动态 SQL 正在生成适当的语句。
我还注意到您的所有varchar声明都缺少长度参数。这使得它们都是一个字符长,这当然不是你的意图。表名是使用 定义的sysname,这几乎与 相同NVARCHAR(128),所以我切换到了。
CREATE PROCEDURE [dbo].[swap_Collect]
@Table varchar,
@UniqueColumn varchar
AS
-- Moving the variable declaration so we can use them in both the IF and the ELSE
DECLARE @Table_temp as varchar = @Table + '_temp'
,@SQL varchar(500)
,@NL varchar(2) = CONCAT(CHAR(10),CHAR(13));
-- This is a new line character to make the dynamic code more readable.
BEGIN
IF (OBJECT_ID(@Table) IS NOT NULL ) --The variable is fine here.
BEGIN
-- Delete from the base table here.
SET @SQL = CONCAT(
'DELETE FROM ',QUOTENAME(@Table), @NL,
'WHERE ',QUOTENAME(@UniqueColumn),
' IN (SELECT ',QUOTENAME(@UniqueColumn),' FROM ', QUOTENAME(@Table_temp),');');
--PRINT @SQL;
EXEC sp_executesql @SQL;
-- Insert into the base table here.
SET @SQL = CONCAT(
'INSERT INTO ', QUOTENAME(@Table), @NL,
'SELECT * FROM ', QUOTENAME(@Table_temp),';');
--PRINT @SQL;
EXEC sp_executesql @SQL;
SELECT 1
END
ELSE
BEGIN
-- Insert into the base table here.
-- SELECT...INTO only works if the target table doesn't exist. Since @Table does exist
-- we'll use INSERT INTO instead.
SET @SQL = CONCAT(
'INSERT INTO ', QUOTENAME(@Table), @NL,
'SELECT * FROM ', QUOTENAME(@Table_temp),';');
--PRINT @SQL;
EXEC sp_executesql @SQL;
SELECT 1
END
END
由于它使用它,这里有一个很好的参考。动态 SQL 的注意事项