存储过程中的表名作为参数

时间:2016-04-28 14:53:00

标签: sql-server tsql stored-procedures

我将存储过程拆分源表存储到4个表中,工作正常。见下文。

现在我改为以下一个

ALTER PROCEDURE Doc124NEW_new (@DMIGRATIONNEW nvarchar(255)) 


AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
SET NOCOUNT ON;


DECLARE @DMIGRATION nvarchar(255);
DECLARE @count int = 0;
DECLARE @numRows int = 0;

SELECT @DMIGRATION = QUOTENAME( TABLE_NAME )
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = @DMIGRATIONNEW

--SELECT @count = COUNT(*) FROM '+@DMIGRATION+'

SELECT  @count = p.rows 
FROM    sys.partitions p
JOIN    sys.tables t
ON      p.[object_id] = t.[object_id]
AND     p.index_id < 2
WHERE   OBJECT_NAME(t.[object_id]) = @DMIGRATION
SELECT @numRows = @count / 4

DECLARE @sql AS NVARCHAR(MAX)
    SELECT @sql='SELECT TOP  '+ @numRows +' * 
INTO [dbo].[DMIGRATIONnew1]
FROM '+@DMIGRATION
EXEC(@SQL)


DECLARE @sql1 AS NVARCHAR(MAX)
    SELECT @sql1= 'SELECT TOP '+@numRows+' * 
INTO [dbo].[DMIGRATIONnew2]
FROM '+@DMIGRATION+'
WHERE [cindex] NOT IN (SELECT TOP '+@numRows+' [cindex] FROM '+@DMIGRATION+')'
EXEC(@SQL1)

DECLARE @sql2 AS NVARCHAR(MAX)
    SELECT @sql2='SELECT TOP '+@numRows+' * 
INTO [dbo].[DMIGRATIONnew3]
FROM '+@DMIGRATION+'
WHERE [cindex] NOT IN (SELECT TOP '+@numRows+' * 2 [cindex] FROM '+@DMIGRATION+')'

EXEC(@SQL2)

DECLARE @sql3 AS NVARCHAR(MAX)
    SELECT @sql3='SELECT * 
INTO [dbo].[DMIGRATIONnew4]
FROM '+@DMIGRATION+'
WHERE [cindex] NOT IN (SELECT TOP '+@numRows+' * 3 [cindex] FROM '+@DMIGRATION+')'
EXEC(@SQL3)

END

并且喜欢错误 将varchar值'SELECT TOP'转换为数据类型int时转换失败。

这是SP

后面的错误消息

Msg 102,Level 15,State 1,Line 4 '2'附近的语法不正确。 Msg 102,Level 15,State 1,Line 4 '3'附近的语法不正确。

alter PROCEDURE Doc124NEW_new1 (@DOCMIGRATIONNEW nvarchar(255)) 


AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
SET NOCOUNT ON;
--DROP TABLE [dbo].[DOCMIGRATIONnew1]
--DROP TABLE [dbo].[DOCMIGRATIONnew2] 
--DROP TABLE [dbo].[DOCMIGRATIONnew3]
--DROP TABLE [dbo].[DOCMIGRATIONnew4]

DECLARE @DOCMIGRATION nvarchar(255);
DECLARE @count int = 0;
DECLARE @numRows int = 0;
DECLARE @sql AS NVARCHAR(MAX)
DECLARE @sql1 AS NVARCHAR(MAX)
DECLARE @sql2 AS NVARCHAR(MAX)
DECLARE @sql3 AS NVARCHAR(MAX)

SELECT @DOCMIGRATION = QUOTENAME( TABLE_NAME )
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = @DOCMIGRATIONNEW

--SELECT @count = COUNT(*) FROM '+@DOCMIGRATION+'

SELECT  @count = p.rows 
FROM    sys.partitions p
JOIN    sys.tables t
ON      p.[object_id] = t.[object_id]
AND     p.index_id < 2
WHERE   OBJECT_NAME(t.[object_id]) = @DOCMIGRATION
SELECT @numRows = @count / 4


SELECT @sql='SELECT TOP ('+CAST(@numRows AS NVARCHAR(6))+') * 
INTO [dbo].[DOCMIGRATIONnew1]
FROM '+@DOCMIGRATION
EXEC(@SQL)



SELECT @sql1= 'SELECT TOP '+CAST(@numRows AS NVARCHAR(6))+' * 
INTO [dbo].[DOCMIGRATIONnew2]
FROM '+@DOCMIGRATION+'
WHERE [cindex] NOT IN (SELECT TOP '+CAST(@numRows AS NVARCHAR(6))+' [cindex] FROM '+@DOCMIGRATION+')'
EXEC(@SQL1)


SELECT @sql2='SELECT TOP '+CAST(@numRows AS NVARCHAR(6))+' * 
INTO [dbo].[DOCMIGRATIONnew3]
FROM '+@DOCMIGRATION+'
WHERE [cindex] NOT IN (SELECT TOP '+CAST(@numRows AS NVARCHAR(6))+' * 2 [cindex] FROM '+@DOCMIGRATION+')'
EXEC(@SQL2)


SELECT @sql3='SELECT * 
INTO [dbo].[DOCMIGRATIONnew4]
FROM '+@DOCMIGRATION+'
WHERE [cindex] NOT IN (SELECT TOP '+CAST(@numRows AS NVARCHAR(6))+' * 3 [cindex] FROM '+@DOCMIGRATION+')'
EXEC(@SQL3)

END

1 个答案:

答案 0 :(得分:0)

没有其他character string

QUOTENAME()会将您的表名包装在方括号中。

所以当你进一步向下寻找

SELECT @count = 'COUNT(*) FROM ['+@DMIGRATION+']'

你基本上是在写这个

SELECT @count = 'COUNT(*) FROM [[TABLE_NAME]]'

删除方括号,它应该适合你。

您还将@count变量定义为INT,但是当您尝试将其设置为某个值时,您似乎正在尝试将其设置为字符串。

SELECT @count = 'COUNT(*) FROM ['+@DMIGRATION+']';

而是尝试从sys.partitions

中获取行
SELECT  @count = p.rows 
FROM    sys.partitions p
JOIN    sys.tables t
ON      p.[object_id] = t.[object_id]
AND     p.index_id < 2
WHERE   OBJECT_NAME(t.[object_id]) = @DMIGRATION;