如何命名在存储过程中返回的数据集表?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何命名在存储过程中返回的数据集表?相关的知识,希望对你有一定的参考价值。
我有以下存储过程
Create procedure psfoo ()
AS
select * from tbA
select * from tbB
然后我以这种方式访问数据:
Sql Command mysqlCommand = new SqlCommand("psfoo" , DbConnection)
DataSet ds = new DataSet();
mySqlCommand.CommandType = CommandType.StoredProcedure;
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter();
mySqlDataAdapter.SelectCommand = mySqlCommand;
mySqlDataAdapter.Fill(ds);
现在,当我想访问我的表时,我必须这样做:
DataTable datatableA = ds.Tables[0];
DataTable datatableB = ds.Tables[1];
数据集Tables属性也通过字符串(而不是int)获得了一个访问器。
是否有可能在SQL代码中指定表的名称,以便我可以写这个:
DataTable datatableA = ds.Tables["NametbA"];
DataTable datatableB = ds.Tables["NametbB"];
我正在使用SQL Server 2008,如果这有所不同。
据我所知,从存储过程中,你不能这样做。但是,您可以在检索DataSet后设置名称,然后再使用它们。
ds.Tables[0].TableName = "NametbA";
这对我有用,但需要一些额外的工作来获得预期的表名:
Dim tableCount As Integer = 3
Dim tables(tableCount) As DataTable
tables(0) = (New DataTable("Employee"))
tables(1) = (New DataTable("Manager"))
tables(2) = (New DataTable("Department"))
dsUControlData.Tables.Add(tables(0))
dsUControlData.Tables.Add(tables(1))
dsUControlData.Tables.Add(tables(2))
'Fill required tables
da.Fill(0, 0, tables)
Return dsUControlData
你可以试试这个:
在您的程序中添加以下行
Select 'TableName1','TableName2';
使用C#:
for (var i=0;i<ds.Tables[0].Columns.Count;i++)
{
ds.Tables[i + 1].TableName = ds.Tables[0].Columns[i].ColumnName;
}
试试这个
YourDataAdapter.Fill(ds, "Table");
试试这个。在MS SQL 2008 R2中,我总是使用它。
mySqlDataAdapter.Fill(ds,"NameTableA");
应该从原始表中使用select到“yourtablename”,这只是一个例子,找到select into语句的正确语法。
这是满足您要求的正确方法。谢谢。
这个问题是一个旧的问题但是,它是google搜索的顶部,呵呵。也许它会帮助某人......
答案是肯定的,可以在代码中指定表的名称,以便您可以通过名称访问DataSet中的DataTable。
首先,我必须解释TableMapping的工作原理。如果我们没有用SqlDataAdapter指定TableMappings(SqlDataAdapter将填充我们的DataSet),那么默认情况下,第一个表将命名为“Table”,第二个将命名为“Table1”,第三个将命名为“Table2”等。
因此,当我们想在DataSet中命名DataTable时,我们使用它如下:
//...
System.Data.DataSet myDataSet = new System.Data.DataSet();
using (System.Data.SqlClient.SqlDataAdapter dbAdapter = new System.Data.SqlClient.SqlDataAdapter(dbCommand))
{
dbAdapter.TableMappings.Add("Table", "MyFirstTitleForTableOne");
dbAdapter.TableMappings.Add("Table1", "MyFirstTitleForTableTwo");
dbAdapter.TableMappings.Add("Table2", "MyFirstTitleForTableThree");
dbAdapter.TableMappings.Add("Table3", "MyFirstTitleForTableFour");
//...
dbAdapter.Fill(myDataSet);
}
//...
而且,现在我们可以通过标题访问DataTable:
System.Data.DataTable firstTable = myDataSet.Tables["MyFirstTitleForTableOne"];
System.Data.DataTable secondTable = myDataSet.Tables["MyFirstTitleForTableTwo"];
抱歉,我没有编写检查null(myDataSet)的代码或者在try / catch块中设置它,因为我认为这与此问题无关。
可能这可能是解决方法
Create procedure psfoo ()
AS
select * ,'tbA' as TableName from tbA
select * ,'tbB' as TableName from tbB
然后在C#代码中
foreach (DataTable dt in ds.Tables)
{
if (dt.Rows[0]["TableName"].ToString().Contains("tbA"))
{
}
else if (dt.Rows[0]["TableName"].ToString().Contains("tbB"))
{
}
}
存储过程:
select 'tbA','tbB','tbC'
select * from tbA
select * from tbB
select * from tbC
前端:
int i = 1;
foreach (string tablename in dsEmailData.Tables[0].Rows[0][0].ToString().Split(','))
{
dsEmailData.Tables[i++].TableName = tablename;
}
希望这可以帮助
有没有理由在填写DataSet后无法手动命名它们?
mySqlDataAdapter.Fill(ds);
ds.Tables[0].TableName = "NametbA";
ds.Tables[1].TableName = "NametbB";
我不知道如何命名从存储过程中作为多个结果集的一部分返回的DataTables,但如果您知道存储过程返回的内容,那么手动命名它们应该可以正常工作。
编辑
知道您可以控制存储过程,一种替代方法可能是在表示表名的结果集中添加一列。然后你可以做类似的事情:
foreach (DataTable table in ds.Tables)
{
table.TableName = table.Rows[0]["TableName"].ToString();
}
但是,这依赖于实际包含行的存储过程返回的结果集。如果它们不包含行,那么您必须将它包装在“if”语句中,并且不是每个表都会得到一个名称。
好主意,它更好的过程返回三个结果集而不是添加表名
firs trow of each table
select 'tbA' FirstTableName,'tbB' SecondTableName
select * from tbA
select * from tbB
每次执行过程时,表[0]都会有一行继续跟随选择表名
另一个想法是传递表名作为过程的输出参数
Create procedure psfoo (@tb1 varchar(50) output,@tb2 varchar(50) output)
AS
set @tb1='tbA'
set @tb2 'tbB'
select * from tbA
select * from tbB
如果此方法限制您并且选择是变量,您可以创建这样的过程
Create procedure psfoo ()
AS
select * from tbA
select * from tbB
return 'tbA,tbB'
通过将过程返回值拆分为string [],您可以获得表格的名称
returnvalue=@returnvaluefromSp.split(new char[]{','});
string tablenam1=returnvalue[0];
string tablenam2=returnvalue[1];
为了给数据集中的所有表提供名称,我们需要在SP或T-Sql的最后再写一个select查询。
lsqry = New System.Text.StringBuilder
lsqry.AppendLine("select * from Bill_main")
lsqry.AppendLine("select * from serviceonly")
lsqry.AppendLine("select * from PendingService")
lsqry.AppendLine("select * from T_servicebillhd")
lsqry.AppendLine("select 'Bill_Main','serviceonly','PendingService','T_servicebillhd'")
Using con As New SqlConnection(lsConnection)
Try
con.Open()
Using cmd As SqlCommand = con.CreateCommand
With cmd
.CommandText = lsqry.ToString
.CommandType = CommandType.Text
End With
Using da As New SqlDataAdapter(cmd)
da.Fill(DS)
End Using
End Using
For li As Integer = 0 To DS.Tables.Count - 2
DS.Tables(li).TableName = DS.Tables(DS.Tables.Count - 1).Rows(0).Item(li)
Next
Catch ex As Exception
End Try
End Using
在上面的例子中,我使用的是t-sql语句而不是SP。其中我写了4个选择查询,最后一个是这些表的表名。并获取包含表名称的最后一个表,并使用TableName属性将其分配给表。
我有一个存储过程访问我企业中的所有数据并返回多个结果集。在每个结果集之前使用名称进行选择对我来说更有意义。像这样:
SELECT 'Customers' AS TableName
SELECT ID, Name FROM dbo.Customer
SELECT 'Orders' AS TableName
SELECT ID, Created FROM dbo.[Order]
然后,当我迭代MyDataSet.Tables时,我只有一个循环和直接查找逻辑。没有主元数据表可以跟上。这甚至在没有返回表时也能工作。如果未返回表数据,则不返回匹配的元数据,这对我来说很有意义。
For Each DataTable As DataTable In MyDataSet.Tables
MyDataSet.Tables(MyDataSet.Tables.IndexOf(DataTable) + 1).TableName = DataTable.Rows(0)("TableName")
Next
如果我想在元数据表中添加更多列,我可以。
我知道这是一个非常古老的帖子,但要回答......是的,这是可能的。只需在dataadapter "TableName"
调用中添加Fill
即可。
MyDataAdapter.Fill(ds, "TableName");
我是C#家伙,但你明白了。
我知道这是一个老问题,但我想今天做同样的事情,所以我不只是循环遍历结果数据集的索引。因为如果存储过程按选择的顺序改变.net代码会炸毁。
我想出了一个解决方案,用表名添加一个列到结果集,并使用case语句来查看表中是否存在该列。但它似乎只是在移动代码。刚刚使SQL静态化。另外,如果在不同的表中有一个名为相同的列,那该怎么办呢?瘸...
myDS.Tables(i).Columns.Contains("TableName")
您可以返回一个额外的结果集来命名表,如下所示:
SELECT 'firstTableName' AS tbl
UNION
SELECT 'secondTableName' AS tbl
UNION
...
如果这是第一个结果集,您可以使用它来命名后续结果集。
以上是关于如何命名在存储过程中返回的数据集表?的主要内容,如果未能解决你的问题,请参考以下文章