我要做的是:我创建了一个T-SQL存储过程,它从多个表中返回一个列。
CREATE PROCEDURE [dbo].[Search_]
(@am VARCHAR(12))
AS
BEGIN
SET NOCOUNT ON;
DECLARE @DBName VARCHAR(128)
DECLARE Tbl CURSOR READ_ONLY FOR
SELECT LEFT(TABLE_NAME, 27) AS Tbl
FROM ap.INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE LEFT('STORED_PRODUCTS_FR_[0-9]_%', 27)
AND SUBSTRING(TABLE_NAME, 20, 2) LIKE '%[0-9]%'
AND SUBSTRING(TABLE_NAME, 23, 1) = '_'
ORDER BY
CONVERT(INT, SUBSTRING(TABLE_NAME, 24, 4)) ASC,
CONVERT(INT, SUBSTRING(TABLE_NAME, 21, 2)) ASC
OPEN Tbl
FETCH NEXT FROM Tbl INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @SQL VARCHAR(100)
SET @sql = 'SELECT [column 3] FROM ' + @DBName + ' WHERE [COLUMN 4] = ' + @am + '';
EXEC(@sql)
FETCH NEXT FROM Tbl INTO @DBName
END
END
CLOSE Tbl
DEALLOCATE Tbl
然后在asp.net中,我想填充gridview ...
try
{
SqlDataAdapter dt = new SqlDataAdapter();
string message = string.Empty;
con.Open();
cmd.CommandText = "Search_";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@am", am.Text);
cmd.Connection = con;
dt.SelectCommand = cmd;
DataTable dTable = new DataTable();
dt.Fill(dTable);
GridView1.DataSource = dTable;
GridView1.DataBind();
}
catch (Exception ex)
{
throw ex;
}
这只返回存储过程的单行(第一行)。
我究竟做错了什么?似乎这些价值观会被覆盖。
任何人的帮助....
您的存储过程返回两行,但由于每行都在不同的select语句中选择,因此DataAdapter
只能使用返回的第一行来填充DataTable
。如果你填充DataSet
,它将包含2个DataTable
实例。
请注意您的存储过程表明您的数据库设计存在缺陷 - 拥有多个存储相同类型实体的表是数据库的糟糕设计。但是,我不确定这是怎么回事。
无论如何,要使用快速补丁解决此问题,您可以将过程更改为以下内容:
CREATE PROCEDURE [dbo].[Search_] (@am varchar(12))
AS
BEGIN
SET NOCOUNT ON;
DECLARE @DBName varchar(128)
declare @SQL varchar(max) = ''
DECLARE Tbl CURSOR READ_ONLY FOR
select LEFT(TABLE_NAME,27) as Tbl from ap.INFORMATION_SCHEMA.TABLES
where TABLE_NAME like left('STORED_PRODUCTS_FR_[0-9]_%',27)
and SUBSTRING(TABLE_NAME , 20,2) like '%[0-9]%'
and SUBSTRING(TABLE_NAME , 23,1) = '_'
order by CONVERT(int , substring(TABLE_NAME,24,4)) asc ,
CONVERT(int , substring(TABLE_NAME,21,2)) asc
OPEN Tbl
FETCH NEXT FROM Tbl INTO @DBName
WHILE @@FETCH_STATUS = 0
BEGIN
set @sql += 'union all select [column 3] from '+@DBName+' WHERE [COLUMN 4] ='+@am+' ';
FETCH NEXT FROM Tbl INTO @DBName
END
CLOSE Tbl
DEALLOCATE Tbl
SET @sql = STUFF(@Sql, 1, 10, '') -- Remove the first union all
exec(@sql)
END
在你的脚本中,最后的end
应放在DEALLOCATE Tbl
之后,并且用于调用sp,它更好地返回多个记录集以使用DataSet或DataReader:
var dataset = new DataSet();
using(var cnnn = new SqlConnection(cnnString))
{
var adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("dbo.Search_", cnnn);
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.Fill(dataset);
}
dataset.Tables => gives u all the results of exec(@sql)
由于每个结果集都返回相同的列名和结构,因此您可以将它们全部合并到一个tb中:
var allTbs = dataset.Tables[0].Copy();
for(int i = 1; i < dataset.Tables.Count; i++)
allTbs.Merge(dataset.Tables[i]);