目前,我有一个存储过程,它返回所有列Example
。我正在使用此存储过程从多个表中检索数据,每个表具有不同的列数和明显不同的列名,因此(Select *)
很方便。但是,现在我只需要检索每个表中的特定列,所以我想传递这样的参数:
Select *
此处的问题是未设置要为列传递的参数数量,因为该表可以包含任意数量的列。有没有办法使用某种循环或动态赋值,以便我可以传递任意数量的参数作为列名?
我知道我只能过滤掉我想要使用的列,而忽略其余的,但这在我的情况下不起作用。我需要存储过程不返回一些包含敏感数据的特定列。
我在我的应用程序中使用SQL Server 2008,ASP.NET MVC 4和C#。
答案 0 :(得分:0)
如果您能够修改存储过程,则可以轻松地将所需的列定义作为参数并使用自动创建的临时表:
CREATE PROCEDURE sp_GetDiffDataExample
@columnsStatement NVARCHAR(MAX) -- required columns statement (e.g. "field1, field2")
AS
BEGIN
DECLARE @query NVARCHAR(MAX)
SET @query = N'SELECT ' + @columnsStatement + N' INTO ##TempTable FROM dbo.TestTable'
EXEC sp_executeSql @query
SELECT * FROM ##TempTable
DROP TABLE ##TempTable
END
在这种情况下,您不需要手动创建临时表 - 它是自动创建的。
希望这有帮助。
答案 1 :(得分:0)
您只需传递一个参数,该参数是您要选择的列的逗号分隔字符串,并构建动态sql字符串。
@sql = 'SELECT ' + @param + ' FROM MyTable...';
EXECUTE (@sql);
如果您使用动态SQL解决方案,则应注意防范SQL注入攻击。
您可能还会考虑继续从存储过程中获取所有列,并仅显示用户在前端所需的列。
答案 2 :(得分:0)
虽然我真的不喜欢这个问题的存储过程方法(我同意@Gusman在C#中构建查询是一种更好的方法),但是你可以使存储过程工作而不会打开SQL注入攻击。以下示例是一种简单的方法:
假设有问题的表格中包含名为COL1
,COL2
和COL3
的列。存储过程将接受名为varchar(max)
的{{1}}参数,其代码如下:
@IncludeCols
是的,将返回每个名称的列,但数据将仅来自名称在参数中的列。例如,如果您想要SELECT CASE WHEN @IncludeCols LIKE '%#COL1#%' THEN COL1 ELSE '' END AS COL1,
CASE WHEN @IncludeCols LIKE '%#COL2#%' THEN COL2 ELSE '' END AS COL2,
CASE WHEN @IncludeCols LIKE '%#COL3#%' THEN COL3 ELSE '' END AS COL3
FROM <Table name>
WHERE <Where clause>
和COL1
,则参数值为COL3
。 #COL1#COL3#
很重要,必须位于每个列名的每一侧,否则任何#
子句都可能会出现误报。
答案 3 :(得分:0)
如果要将数据导出到Excel,那么最好的方法可能是有一个存储过程可以返回所有列,而不是从不导出的列(密码,其他受保护的数据,也许是时间戳)然后过滤掉前端的任何其他不需要的列。
您应该从不使用SELECT *
有几个原因。定义您的应用程序需要的内容并对其进行编程。