【问题标题】:Naming DataSet.table after performing SQLCommand (Select) Query执行 SQLCommand (Select) Query 后命名 DataSet.table
【发布时间】:2023-04-08 08:52:01
【问题描述】:

在存储过程 MS SQL 我的查询是:

SELECT *  
FROM ContentReportRequests a,UserPreferences d
WHERE  a.UserID = d.UserID and a.ID =@ID

我想给结果表起个名字。 我该怎么做?

我想把它拉到 ADO.Net DataSet.tables["NAME"]

【问题讨论】:

  • 不知道你在这里问什么。您正在选择 * ,这将返回所有 a.* 和所有 d.*。如果要单独命名字段,则可以单独命名。
  • 你将如何/在哪里使用这个名字?
  • 我在.Net DataTable.tables["NAME"]中使用它

标签: sql-server select stored-procedures


【解决方案1】:

我可以想象你可能想说的几件事。

如果您想保留此结果集,以便在以后的多个查询中使用,您可能正在寻找 SELECT INTO:

SELECT * into NewTableName
FROM ContentReportRequests a,UserPreferences d
WHERE  a.UserID = d.UserID and a.ID =@ID

其中NewTableName 是一个新名称,并且将创建一个新的(永久)表。如果您希望该表在完成后消失,请在名称前加上 #,使其成为临时表。

或者,您可能只是想将其吸收到一个更大的查询中,在这种情况下,您会考虑将其设为子选择:

SELECT *
FROM (SELECT *  
FROM ContentReportRequests a,UserPreferences d
WHERE  a.UserID = d.UserID and a.ID =@ID
) NewTableName
WHERE NewTableName.ColumnValue = 'abc'

或 CTE:

WITH NewTableName AS (
    SELECT *  
    FROM ContentReportRequests a,UserPreferences d
    WHERE  a.UserID = d.UserID and a.ID =@ID
)
SELECT * from NewTableName

最后,您可能正在谈论将结果集拉入例如ADO.Net 数据表,并且您希望自动设置名称。我不确定这是否可行。

【讨论】:

  • 最后两个例子会执行更多的运行时间吗?
  • @Mark T - 他们不应该这样做。查询优化器相当聪明,绝大多数时间都将用于 I/O(对于任何需要考虑性能的大量数据)
【解决方案2】:

您可以使用table 类型的变量。在这里阅读更多:Table Variables In T-SQL

【讨论】:

  • 但是如果我将它插入到新表中,这会将 o(n) 添加到运行时
  • @Mark 好吧,你的问题不是很具体。
【解决方案3】:

在存储过程中:

select  CH.PrimaryKey, CH.Name,
        NULL    "CustomerHeader"
from CustomerHeader "CH";
--
select  CD.PrimaryKey, CD.ShipTo,
        NULL    "CustomerDetail"
from CustomerDetail "CD";
--
select  *, NULL "Orders"
from    OrderTable;

在 Vb.Net 代码中:

Dim ds As DataSet = Nothing
ds = SqlExecute();
Dim dtCustHeader As DataTable = Nothing
Dim dtCustDetail As DataTable = Nothing
Dim dtOrders As DataTable = Nothing
For Each dt As DataTable In ds.tables
    Select Case True
        Case dt.Columns.Contains("CustomerHeader")
            dtCustHeader = dt
        Case dt.Columns.Contains("CustomerDetail")
            dtCustDetail = dt
        Case dt.Columns.Contains("Orders")
            dtOrders = dt
    End Select
Next

您无法在结果集中命名表,这有点愚蠢(或愚蠢)。 但这可以让您到达那里,而无需在每一行中重复表名的巨大字节数。

为每一行传回 NULL 值仍然存在开销。也许传递一个 BIT 值会更小......

另一种方法是始终使用 column(0): 在 SQL 中:

select NULL "CustomerDetail", CustName,Addr1,Addr2... from CustomerDetail;

在 vb.net 中:

    Dim ds As DataSet = Nothing
    ds = SqlExecute();
    Dim dtCustHeader As DataTable = Nothing
    Dim dtCustDetail As DataTable = Nothing
    Dim dtOrders As DataTable = Nothing
    For Each dt As DataTable In ds.Tables
        Dim tblName As String = dt.Columns(0).ColumnName
        Select Case tblName.ToUpper
            Case "CUSTOMERDETAIL" : dtCustHeader = dt
            Case "CUSTOMERDETAIL" : dtCustDetail = dt
            Case "ORDERS" : dtOrders = dt
        End Select
    Next

即使查询返回零行,这些方法也会获取您的表名。

最适合最后使用...一种在每次从 SQL 存储过程中自动命名数据集中表的方法(在您的代码的帮助下):

Dim ds As DataSet = Nothing
ds = SqlExecute();
For Each dt As DataTable In ds.Tables
    dt.TableName = dt.Columns(0).ColumnName
Next

在此之后,您可以在存储过程中使用您控制的名称访问您的表......因为它应该从第一天开始!

EDIT:选择性实施: 将模式中的第一列命名为“TN:Customer”。 您的旧存储过程正常工作,只会影响您希望修改的存储过程。

            For Each dt As DataTable In mo_LastDataset.Tables
                Dim tblName() As String = dt.Columns(0).ColumnName.Split(":")
                If tblName.Length >= 2 AndAlso tblName(0).ToUpper = "TN" Then
                    dt.TableName = tblName(1)
                End If
            Next

...大卫...

【讨论】:

    【解决方案4】:
    SELECT * AS MyTableName  
      FROM ContentReportRequests a, UserPreferences d  
     WHERE a.UserID = d.UserID and a.ID =@ID  
    

    【讨论】:

    • 我不记得确切的语法。也许把 AS ... 部分放在最后。但应该很简单。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2013-07-08
    • 2021-12-14
    相关资源
    最近更新 更多