如何在存储过程中传递datatable

时间:2013-08-07 08:22:48

标签: sql-server

我有两个数据表 dt1和dt2

我的存储过程如下

ALTER procedure [dbo].[Sp_ShowAllEmpLeaveSummary]
@TableName1 nvarchar(128) ,
@TableName2 nvarchar(128)
as
begin

DECLARE @Columns VARCHAR(MAX)

SELECT @Columns = COALESCE(@Columns + ',' + name + '', '' + name + '') FROM (
    SELECT DISTINCT 
    'CAST(ISNULL('+@TableName1 +'.' + name + ',0) AS VARCHAR) + ''/'' + CAST('+@TableName2 +'.' + name + ' AS VARCHAR) AS ' + name + ' ' AS name 
FROM sys.columns 
WHERE NAME LIKE '%leave%' 
AND object_id IN (SELECT object_id FROM sys.tables WHERE name IN (''+@TableName1 +'', ''+@TableName2 +''))) LeaveColumns

DECLARE @SQL NVARCHAR(MAX)
SET @SQL = N'
SELECT 
'+@TableName1 +'.empid, 
'+@TableName2 +'.empname, ' + @Columns + ' 
FROM dt1 
INNER JOIN '+@TableName2 +' ON '+@TableName1 +'.empid='+@TableName2 +'.empid'    


EXECUTE(@SQL)
end

在Ui我传递像这样的参数

 cmd4.Parameters.Add(new SqlParameter("@TableName1", SqlDbType.Structured)).Value = dt1;
   cmd4.Parameters.Add(new SqlParameter("@TableName2", SqlDbType.Structured)).Value = dt2; 

但显示错误操作数类型冲突:表类型与nvarchar(128)不兼容。我也可以解决这个问题

由于

2 个答案:

答案 0 :(得分:0)

如果要传递表,则必须将表定义为自定义类型,并将其传递给过程。

请参阅http://technet.microsoft.com/en-us/library/bb510489.aspx

但看起来你只想传递这个名字。

所以C#类型应该是SqlDbType.NVarChar

此外,您应该清理输入以防止SQL注入,而不是使用sp_

为存储过程添加前缀

答案 1 :(得分:0)

我不确定我是否已完全理解您的SP以及您是如何调用它的,但是当您在SP中构建SQL命令时,您必须将数据表的名称也作为字符串传递并将其放入命令中此

ALTER procedure empl
 @tb1 nvarchar(128) ,
 @tb2 nvarchar(128) 
as
BEGIN
DECLARE @Columns VARCHAR(MAX)
SELECT @Columns = COALESCE(@Columns + ',' + name + '', '' + name + '') FROM (
    SELECT DISTINCT 
    'CAST(ISNULL('+@tb1 +'.' + name + ',0) AS VARCHAR) + ''/'' + CAST('
                  +@tb2 +'.' + name + ' AS VARCHAR) AS ' + name + ' ' AS name 
    FROM sys.columns 
    WHERE NAME LIKE '%leave%' 
    AND object_id IN (SELECT object_id FROM sys.tables 
                      WHERE name IN (@tb1,@tb2))
) LeaveColumns

DECLARE @SQL NVARCHAR(MAX)
SET @SQL = N'
SELECT 
'+@tb1 +'.empid, 
'+@tb2 +'.empname, ' + @Columns + ' 
FROM '+@tb1+'
INNER JOIN '+@tb2 +' ON '+@tb1 +'.empid='+@tb2 +'.empid'    

-- SELECT @SQL; -- for debug purposes
EXECUTE(@SQL)
END

你的意思是dt1成为SP中的@tb1吗? (为了更好的可读性,我缩短了变量名称)