2015-11-11 24 views
5

Bazı nedenlerle saklı yordamım C# içindeki kod arkasından herhangi bir hata olmadan yürütülür, ancak saklı yordamın yazıldığı hiçbir şey silinmez. Tüm doğru parametrelere ve her şeye sahibim. SQL Server'dan sorguyu C# kodundaki tüm aynı parametrelerle çalıştırdım ve mükemmel çalışıyor. SQL Server'dan çalıştırdığımda neden çalıştığını anlamıyorum ama Visual Studio'daki C# kodumdan çalıştırdığımda çalışmaz.Saklı yordam dinamik sql metniyle düzgün çalışmıyor

Verileri saklanan prosedüre ileten C# kodum.

string reportType = "PostClaim"; 
string GRNBRs = "925','926','927"; 
string PUNBRs = "100','100','100"; 
string beginningDates = "20120401"; 
string endDates= "20120430"; 

try 
{ 
    conn = new SqlConnection(ConnectionInfo); 
    conn.Open(); 
    SqlDataAdapter da = new SqlDataAdapter("RemoveReport", conn); 
    da.SelectCommand.CommandType = CommandType.StoredProcedure; 
    da.SelectCommand.Parameters.AddWithValue("@ReportType", reportType); 
    da.SelectCommand.Parameters.AddWithValue("@GRNBR", GRNBRs); 
    da.SelectCommand.Parameters.AddWithValue("@PUNBR", PUNBRs); 
    da.SelectCommand.Parameters.AddWithValue("@DATE1", beginningDates); 
    da.SelectCommand.Parameters.AddWithValue("@DATE2", endDates); 
    da.SelectCommand.CommandTimeout = 360; 
} 
catch (SqlException ex) 
{ 
    //something went wrong 
    throw ex; 
} 
finally 
{ 
    if (conn.State == ConnectionState.Open) 
     conn.Close(); 
} 

Burada saklı yordamım var. Dinamik SQL metin ile yürütülür.

DELETE FROM MonthlyReportSchedule 
WHERE Report='PostClaim' AND 
     PUNBR IN ('100','100','100') AND 
     [Group] IN ('925','926','927') AND 
     StartedAt BETWEEN '2012-04-01' AND '2012-04-30' 

Aslında bu sorguyu çalıştırmak için SQL Server girmek

, bu mükemmel çalışıyor: İşte

ALTER PROCEDURE [dbo].[RemoveReport] (
    @ReportType NVARCHAR(20), 
    @GRNBR VARCHAR(4000), 
    @PUNBR VARCHAR(4000), 
    @DATE1 DATETIME, 
    @DATE2 DATETIME 
) 
AS 

DECLARE @SQLTEXT VARCHAR(4000) 
BEGIN 

SET @SQLTEXT = 'DELETE FROM TestingTable 
      WHERE Report='''[email protected]+''' AND 
      PUNBR IN ('''[email protected]+''') AND 
      [Group] IN ('''[email protected]+''') AND 
      StartedAt BETWEEN '''+CONVERT(VARCHAR(10),@DATE1,121)+''' 
      AND '''+CONVERT(VARCHAR(10),@DATE2,121)+'''' 

PRINT @SQLTEXT <---I'll print this out to show you what exactly it is executing. 
EXECUTE (@SQLTEXT) 
END 

PRINT @SQLTEXT çalıştıran şeydir. Ancak C# kodundan çalıştırıldığında neden çalışmaz. Herhangi bir yardım? sizin sql parametreleri birleştirerek

+0

M.Ali'nin cevabına biraz daha ayrıntı eklemek için. Parametrelerdeki tek tırnak içinde C# geçişi, SQL enjeksiyonunu önlemek için değiştirilecek, bu yüzden kırılıyor. – Shaun

+0

Ayrıca SQL profiler kullanarak ortaya çıkan kodu göstermiş ve size neler olduğunu göstermişti. – Shaun

cevap

3

kaçının, kullanmak Parametrelenmiş sorgu,

.....

Sadece params bazı virgülle ayrılmış listelerini olduğunu fark ettik ... Bu deneyin

ALTER PROCEDURE [dbo].[RemoveReport] 
    @ReportType NVARCHAR(20), 
    @GRNBR VARCHAR(4000), 
    @PUNBR VARCHAR(4000), 
    @DATE1 DATETIME, 
    @DATE2 DATETIME 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @SQLTEXT NVARCHAR(MAX); 

    Declare @GRNBR_xml xml,@PUNBR_xml xml; 

    SET @GRNBR_xml = N'<root><r>' + replace(@GRNBR, ',','</r><r>') + '</r></root>'; 
    SET @PUNBR_xml = N'<root><r>' + replace(@PUNBR, ',','</r><r>') + '</r></root>'; 


SET @SQLTEXT = N'DELETE FROM TestingTable 
      WHERE Report = @ReportType 
       AND PUNBR IN (select r.value(''.'',''varchar(max)'') as item 
          from @PUNBR_xml.nodes(''//root/r'') as records(r)) 
       AND [Group] IN (select r.value(''.'',''varchar(max)'') as item 
           from @GRNBR_xml.nodes(''//root/r'') as records(r)) 
       AND StartedAt BETWEEN @DATE1 AND @DATE2' 

EXECUTE sp_executesql @SQLTEXT 
        ,N'@ReportType NVARCHAR(20) , @GRNBR_xml xml, 
         @PUNBR_xml xml,@DATE1 DATETIME,@DATE2 DATETIME' 
         ,@ReportType 
         ,@GRNBR_xml 
         ,@PUNBR_xml 
         ,@DATE1 
         ,@DATE2 
END 

Not

Eğer 925,926,927 olarak virgülle ayrılmış listesini iletmek emin olun ve için bu satırı ekleyerek '925','926','927'

0

deneyin saklı yordam çağrısı çalıştırır

da.SelectCommand.ExecuteNonQuery(); 

Bu

yürütülecek değil.

iyi şanslar

İlgili konular