2017-12-28 81 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에서, 난 단지 저장 프로 시저의 단일 행 (첫 번째)을 반환

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

...있는 gridview를 채울합니다.

내가 뭘 잘못하고 있니? 값이 스스로 덮어 쓰는 것 같습니다.

누구로부터 어떤 도움

....

+0

SP는 원하는대로 SQL Server에서 작동합니까? –

+0

예. 예상대로 2 개의 행을 반환합니다. – Nick

+0

SQL 관리 스튜디오에서 저장 프로 시저를 실행하십시오. 데이터가 어떻게 반환되는지보십시오. 두 행을 가진 하나의 테이블이 아닌 두 테이블이 있습니다 –

답변

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 :

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