我认为这个问题的答案是没有进行的,但我可以使用理智检查。
我有一个返回3个表的proc。表1有23列。表2有12列。表3有2列。我需要运行此proc并将Table1的结果转储到临时表中。我创建了一个@table然后做了这个:
insert @myTable
exec [myDb].dbo.[multitableProc] 'A', 'B', 'C', 100
但是当我这样做时,错误是:
插入错误:列名或数字 提供的值与表不匹配 定义
这让我觉得SQL对我想做的事情非常困惑。我肯定表中有正确的列数,请仔细检查。数据类型是正确的。
总之,我很确定这是不可能的,但是这里有人可能有一个技巧。不允许更改源proc。我确实看到了一个类似的问题,但他试图做一些联合类型的东西,不一样。
答案 0 :(得分:2)
我能想到的唯一方法是使用CLR stored procedure。让CLR sproc调用返回三个表的sproc。然后,只抓取你想要的单个表并从CLR sproc中返回。将CLR sproc的结果插入到@myTable中。我认为这将为您提供额外的间接级别,以消除其他两个结果集中的列不匹配。
好的,我创建了一个大大简化的版本来测试。我从表中返回了两个结果集,一个包含一列,另一个包含两个...
DECLARE @myTable TABLE ( col1 varchar(50) )
INSERT @myTable( col1 )
EXEC TestTable
获取正确的结果......
Msg 213,Level 16,State 7,Procedure TestTable,第23行列名或 提供的值的数量不 匹配表定义。
我创建了这个CLR sproc,只从我的TestTable TSQL sproc中获取第一个结果集(只有一列),并只返回该表...
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void FilterResult()
{
using (var conn = new SqlConnection("context connection = true"))
{
var retVal = new SqlDataRecord( new SqlMetaData("col1",
SqlDbType.NVarChar, 50));
conn.Open();
var cmd = new SqlCommand("exec TestTable", conn);
SqlContext.Pipe.SendResultsStart(retVal);
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
var tmpCol = dr.GetString(0);
retVal.SetString(0, tmpCol);
SqlContext.Pipe.SendResultsRow(retVal);
}
dr.Close();
}
SqlContext.Pipe.SendResultsEnd();
}
}
};
然后,我能够执行......
INSERT @myTable( col1 )
EXEC TestFilter -- note the CLR sproc here instead of the TSQL sproc
......一切都很开心......
(2行(s)受影响)
在一天结束时,它可能比它的价值更麻烦,但它确实可以作为概念证明。 (不保证性能。)