如何获得从 sql 到 vb 的动态数据透视

Posted

技术标签:

【中文标题】如何获得从 sql 到 vb 的动态数据透视【英文标题】:How to get dynamic pivot from sql to vb 【发布时间】:2018-05-31 16:50:55 【问题描述】:

我想根据我找到的元素获得一个动态的结果集。这是我的查询示例:

declare @til DateTime = dateadd(MINUTE, -0, getdate())
declare @fra datetime = DATEADD(MINUTE, -350, @til)

declare @title nvarchar(max) = 'test title'
DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX);

create table errors (collection_id bigint, nr smallint, position smallint, stamp datetime)
create table t (collection_id bigint, collection_name nvarchar(max), nr smallint, [status] smallint, stamp datetime)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(errors.position)
                      from t t
                        left join errors on errors.collection_id = t.collection_id and errors.nr = t.nr
                        where t.Status = 4 and errors.Stamp > @fra and t.collection_name = ''' + @title + ''' and errors.collection_id is not null
                      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') , 1, 1, '');

select @cols

set @query = 'declare @til DateTime = dateadd(MINUTE, -0, getdate())
            declare @fra datetime = DATEADD(MINUTE, -350, @til)

            ;with cte as (select t.collection_name, errors.position, count(errors.Tryksag_Nedtagsfejl_Id) antal
            from t
            left join errors on errors.collection_id = s.collection_id and errors.nr = t.nr
            where t.Status = 4 and errors.Stamp > @fra and and t.collection_name = ''' + @title + '''
            group by t.collection_name, errors.position)

                SELECT collection_name, ' + @cols + ' from 
                cte
            pivot 
            (
                 sum(antal)
                for position in (' + @cols + ')
            ) p '

execute(@query)

到目前为止,我已经做了一个查询,我可以在 SSMS 上运行并给出我想要的输出。应该是这样的:

如何在 vb.net 中提供此结果集?当我只是将其全部作为查询运行时,它不会给我结果(假设它没有看到执行的结果集)

添加了 VB 代码

Dim var_til As Short = 0
            Dim var_fra As Short = -60
            Dim Linie As String = "Red"
            Dim tx = "Test title"
            Dim Stt2 = "declare @til DateTime = dateadd(MINUTE, " & var_til & ", getdate()) " _
                & "declare @fra datetime = DATEADD(MINUTE, " & var_fra & " , @til) " _
                & "DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX) " _
                & "declare @linie as nvarchar(max) = '" & Linie & "' " _
                & "declare @title as nvarchar(max) = '" & tx & "' " _
                & "select @cols = STUFF((SELECT distinct ',' + QUOTENAME(errors.position) " _
                & "from t " _
                & "left join errors on errors.collection_id = t.collection_id And errors.nr = t.nr " _
                & "where t.Status = 4 And errors.Stamp > @fra And t.collection_name = ''' + @title + ''' and errors.collection_id is not null " _
                & "FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') , 1, 1, '') " _
                & " " _
                & "set @query = ';with cte as (select t.collection_name, errors.position, count(errors.Tryksag_Nedtagsfejl_Id) antal " _
                & "from t " _
                & "left join errors on errors.collection_id = s.collection_id And errors.nr = t.nr " _
                & "where t.Status = 4 And errors.Stamp > @fra And And t.collection_name = ''' + @title + ''' " _
                & "group by t.collection_name, errors.position) " _
                & "SELECT collection_name, ' + @cols + ' from " _
                & "cte " _
                & "pivot " _
                & "( " _
                & "sum(antal) " _
                & "for position in (' + @cols + ') " _
                & ") p ' " _
                & "execute(@query) "

            Dim sqlConnection2 As New SqlConnection("Data Source=CONDOR-TI;Initial Catalog=Condor_db;Integrated Security=True")
            Dim cmd2 As New SqlCommand
            Dim reader2 As SqlDataReader
            cmd2.CommandText = Stt2
            cmd2.CommandType = CommandType.Text
            cmd2.Connection = sqlConnection2
            sqlConnection2.Open()
            reader2 = cmd2.ExecuteReader()
            While reader2.Read
                Console.Write(reader2(0))
            End While
            Console.WriteLine()
            sqlConnection2.Close()
            reader2.Close()

【问题讨论】:

你的 VB 代码是什么样的? minimal reproducible example 请:桌子和东西...... 如何在 VB 代码中运行此查询? @SMM 我添加了我运行的 VB 代码。运行查询时没有错误,阅读器只是没有显示任何结果 @zulatin 为什么在应用程序中发布整个代码而不是使用存储过程或表值函数?? 【参考方案1】:

我认为最好创建一个存储过程来执行此 SQL 命令,并使用以下代码从 VB.Net 执行它:

Dim sqlConnection1 As New SqlConnection("Your Connection String")
Dim cmd As New SqlCommand
Dim reader As SqlDataReader

cmd.CommandText = "StoredProcedureName"
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = sqlConnection1

sqlConnection1.Open()

reader = cmd.ExecuteReader()
' Data is accessible through the DataReader object here.

sqlConnection1.Close()

参考

How to: Execute a Stored Procedure that Returns Rows

【讨论】:

【参考方案2】:

您可以分两步运行它。确保在同一连接上运行这两个命令。

在第一个命令中,使用 ExecuteNonQuery 将 cte 选择到 #temp 表中。

在第二个命令调用ExecuteReader()

Dim var_til As Short = 0
Dim var_fra As Short = -60
Dim Linie As String = "Red"
Dim tx = "Test title"
Dim Stt2 = "declare @til DateTime = dateadd(MINUTE, " & var_til & ", getdate()) " _
    & "declare @fra datetime = DATEADD(MINUTE, " & var_fra & " , @til) " _
    & "DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX) " _
    & "declare @linie as nvarchar(max) = '" & Linie & "' " _
    & "declare @title as nvarchar(max) = '" & tx & "' " _
    & "select @cols = STUFF((SELECT distinct ',' + QUOTENAME(errors.position) " _
    & "from t " _
    & "left join errors on errors.collection_id = t.collection_id And errors.nr = t.nr " _
    & "where t.Status = 4 And errors.Stamp > @fra And t.collection_name = ''' + @title + ''' and errors.collection_id is not null " _
    & "FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') , 1, 1, '') " _
    & " " _
    & "set @query = ';with cte as (select t.collection_name, errors.position, count(errors.Tryksag_Nedtagsfejl_Id) antal " _
    & "from t " _
    & "left join errors on errors.collection_id = s.collection_id And errors.nr = t.nr " _
    & "where t.Status = 4 And errors.Stamp > @fra And And t.collection_name = ''' + @title + ''' " _
    & "group by t.collection_name, errors.position) " _
    & "SELECT collection_name, ' + @cols + ' INTO #OUT from " _
    & "cte " _
    & "pivot " _
    & "( " _
    & "sum(antal) " _
    & "for position in (' + @cols + ') " _
    & ") p ' " _
    & "execute(@query) "

dim stt3 as string = "select * from #OUT"

Dim sqlConnection2 As New SqlConnection("Data Source=CONDOR-TI;Initial Catalog=Condor_db;Integrated Security=True")
Dim cmd2 As New SqlCommand
cmd2.CommandText = Stt2
cmd2.CommandType = CommandType.Text
cmd2.Connection = sqlConnection2

Dim cmd3 As New SqlCommand
Dim reader3 As SqlDataReader
cmd3.CommandText = Stt3
cmd3.CommandType = CommandType.Text
cmd3.Connection = sqlConnection2

sqlConnection2.Open()
cmd2.ExecuteNonQuery()
reader3 = cmd3.ExecuteReader()
While reader3.Read
    Console.Write(reader3(0))
End While
Console.WriteLine()
sqlConnection2.Close()
reader3.Close()

【讨论】:

在应用程序代码中贴sql命令不是个好主意,我认为最好使用存储过程或表值函数 我同意。特别是在像 VB 这样的面向行的语言中。至少在 C# 中,所有这些 SQL 都可以在单个字符串块中。我避免像这样嵌入 SQL。我认为这种方法肯定有其他原因。

以上是关于如何获得从 sql 到 vb 的动态数据透视的主要内容,如果未能解决你的问题,请参考以下文章

如何从sql动态转移到vb

MS SQL Server 中的动态数据透视

动态 SQL 使用多列交叉应用来反透视数据

c# 在 SQL 动态数据透视字符串中添加变量

SQL 数据透视表动态

SQL 中特定日期状态的动态数据透视表