2017-12-28 53 views
3

私がやろうとしていること:複数のテーブルから単一の列を返すT-SQLストアドプロシージャを作成しました。tsqlプロシージャ戻り値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 

そしてasp.netで、Iは、GridViewコントロールを移入したい...

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

のみ、ストアドプロシージャの単一の行(最初のもの)を返します。

私は間違っていますか?値が上書きされているようです。

誰から任意の助け....

+0

SPは必要に応じてSQL Serverで動作しますか? –

+0

はい。期待どおりに2行を返します。 – Nick

+0

SQL管理スタジオでストアドプロシージャを実行し、そこにデータが返される方法を参照してください。あなたは2つの行を持つ1つのテーブルを持たない2つのテーブルを持っている可能性があります –

答えて

2

あなたのストアドプロシージャは、両方の行を返しますが、各行は異なるSELECTステートメントで選択されているため、DataAdapterDataTableを埋めるために戻って最初のものを使用することができます。 DataSetを記入する場合は、2 DataTableのインスタンスが含まれます。

ストアドプロシージャは、データベース設計に欠陥があることを示しています。同じタイプのエンティティを格納する複数のテーブルを持つことは、データベースのデザインが悪いことになります。しかし、私はそれがここに当てはまるかどうかはわかりません。

とにかく、迅速なパッチでこの問題を解決するために、あなたはこのような何かにあなたの手順を変更することができますスクリプトで

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

私はちょうどそれをテストして、動作します..上記の解決方法は魅力的です..ありがとう – Nick

+0

喜んで;-) –

0

、最後endDEALLOCATE Tbl後、どのSPを呼び出すために配置する必要がありますデータセットまたは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) 

各結果セットが同じカラム名と構造をretunsので、あなたは1つのTBでそれらのすべてをマージすることができます

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