2017-12-18 466 views
6

Chciałbym uzyskać zestaw wyników, który jest dynamiczny w zależności od tego, które elementy znajduję. Oto przykład z mojej kwerendy:Jak uzyskać dynamiczny pivot z sql do vb

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) 

tej pory zrobiłem kwerendę i może działać na SSMS i daje wyjście pragnę. Który byłby tak:

enter image description here

Jak mogę zrobić to resultset dla mnie dostępne w VB.NET? Kiedy tylko go uruchomić wszystko jako zapytanie robi mi dać wyniki (zakładając, że nie widzi resultset od wykonania) kod

Dodany 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() 
+2

Co robi swój wygląd kodu VB jak? – SMM

+0

[mcve] please: tables and stuff ... – Blag

+0

Jak uruchomić to zapytanie w swoim kodzie VB? – FLICKER

Odpowiedz

4

myślę, że lepiej jest utworzyć przechowywane Procedura wykonania tego polecenia SQL i wykonać go od VB.Net stosując następujący kod:

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() 

Reference

3

Można go uruchomić w dwóch etapach. Upewnij się, że uruchamiasz oba te polecenia w tym samym połączeniu.

W pierwszym poleceniu należy wybrać cte w tabeli #temp za pomocą ExecuteNonQuery.

W drugim ExecuteReader wywołania poleceń()

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() 
+0

Nie jest dobrym pomysłem, aby opublikować polecenie sql w kodzie aplikacji, myślę, że lepiej jest użyć procedur przechowywanych lub funkcji o wartości tabeli – Yahfoufi

+0

Zgadzam się. Zwłaszcza w języku zorientowanym na linie, takim jak VB. Przynajmniej w C# wszystkie te SQL mogą znajdować się w jednym bloku ciągu. Unikam osadzania SQL w taki sposób. Zakładam, że muszą istnieć inne powody takiego podejścia. – suresubs