2017-12-28 57 views
3

Was ich versuche zu tun: Ich habe eine gespeicherte T-SQL-Prozedur erstellt, die eine einzelne Spalte aus mehreren Tabellen zurückgibt.tsql Prozedur Rückgabewerte asp.net

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 

dann in asp.net, möchte ich ein Gridview füllen ...

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; 
} 

dass nur eine einzige Zeile zurückgibt (die erste) der gespeicherten Prozedur.

Was mache ich falsch? Es scheint, dass die Werte sich selbst überschreiben.

Jede Hilfe von jemand ....

+0

Funktioniert Ihr SP in SQL Server wie gewünscht? –

+0

Yes.It gibt 2 Zeilen wie erwartet zurück. – Nick

+0

Führen Sie Ihre gespeicherte Prozedur in SQL Management Studio aus, um zu sehen, wie die Daten dort zurückgegeben werden. Sie haben wahrscheinlich zwei Tabellen mit einer Zeile, nicht eine Tabelle mit zwei Zeilen –

Antwort

2

Rücknahme Ihre gespeicherte Prozedur beide Reihen, aber da jede Zeile in einer anderen select-Anweisung ausgewählt wird, kann die DataAdapter nur die erste der DataTable zu füllen Rückkehr verwenden. Wenn Sie einen DataSet füllen würden, würde es 2 DataTable Instanzen enthalten.

Bitte beachten Sie, dass Ihr gespeichertes Verfahren vorschlägt, dass Sie einen Fehler in Ihrem Datenbankentwurf haben - mehrere Tabellen zu haben, die denselben Typ von Entitäten speichern, ist ein schlechtes Design für eine Datenbank. Ich bin mir aber nicht sicher, ob das der Fall ist.

Wie dem auch sei, dieses Problem mit einem schnellen Patch zu lösen, können Sie Ihr Verfahren zu so etwas wie dies ändern:

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 '[email protected]+' WHERE [COLUMN 4] ='[email protected]+' '; 
     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 
+0

Ich teste es einfach und es funktioniert .. Die obige Lösung funktioniert wie Charme .. Danke – Nick

+0

Froh zu helfen ;-) –

0

In Ihrem Skript, das letzte end sollte nach DEALLOCATE Tbl und für den Aufruf des sp platziert werden, die mehrere Datensatzzurückgibt besser verwenden DataSet oder 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) 

da jede Ergebnismenge Retuns den gleichen Spaltennamen und Struktur Sie sie alle in einem tb zusammenführen können:

var allTbs = dataset.Tables[0].Copy(); 
for(int i = 1; i < dataset.Tables.Count; i++) 
    allTbs.Merge(dataset.Tables[i]); 
Verwandte Themen