sp oluşturmada hata.

MS SQL Server veritabanı ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
Kullanıcı avatarı
dynamo
Üye
Mesajlar: 96
Kayıt: 21 Haz 2005 02:05
Konum: istanbul

sp oluşturmada hata.

Mesaj gönderen dynamo »

sql server query analyzer'da aşağıdaki sp'yi oluşturup kullanabiliyorum.

Kod: Tümünü seç

CREATE PROCEDURE SP_MUSTERI_EKLE 
(@KOD   VARCHAR(20), 
@AD  VARCHAR(20), 
@TUTAR  MONEY)
AS 

IF EXISTS(SELECT KOD FROM TBL_MUSTERI WHERE KOD=@KOD) 
BEGIN 
   RAISERROR('Bu Kod Daha Önce Tanımlanmış.',16,1) 
   RETURN 
END
IF @@ERROR <> 0 GOTO ERROR_HANDLER
BEGIN TRANSACTION 

IF @KOD <> 0 
BEGIN 
   
  INSERT  INTO TBL_MUSTERI VALUES 
    ( 
    @KOD, 
    @AD, 
    @TUTAR 
    ) 
   
   SET @KOD=@@IDENTITY 
  END 
ELSE 
  BEGIN 
   
   UPDATE 
    TBL_MUSTERI 
   SET 
    KOD=@KOD, 
    AD=@AD,     
    TUTAR=@TUTAR 
  END
COMMIT TRANSACTION   
RETURN 
ERROR_HANDLER: 
IF @@TRANCOUNT > 0 ROLLBACK TRAN 
Aynı sp'yi delphi üzerinden ouşturmak zorundayım.
delphide kodu çalıştırdığımda "parametre nesnesi hatalı ,eksik veya uyumsuz" diye hata mesajı veriyor.yukardaki QUERY ANALYZER'de
hatasız oluşturup kullandığım sp'ye delphi'de her türlü eklme-çıkarma
yaptığım halde hep bu hata mesajını veriyor .Bir türlü bu sorunu çözemedim. :x
hatalı yada eksik bir şey var mı? :duvar:

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject);
begin
       ADOCommand1.Cancel;
       ADOCommand1.CommandText :='CREATE PROCEDURE SP_MUSTERI_EKLE '+
                                '(@KOD   VARCHAR(20),'+
                                ' @AD  VARCHAR(20),'+
                                ' @TUTAR  MONEY)'+
                                ' AS'+
                                ' DECLARE @ERROR INT '+
                                ' IF EXISTS(SELECT KOD FROM TBL_MUSTERI WHERE KOD=@KOD) '+
                                ' BEGIN  '+
                                ' RAISERROR(''Bu Kod Daha Önce Tanımlanmış.'',16,1) '+
                                ' RETURN  '+
                                ' END '+
                                ' SET @ERROR = @@ERROR ' +
                                ' IF @@ERROR <> 0 GOTO ERROR_HANDLER  '+
                                ' BEGIN TRANSACTION '+
                                ' IF @KOD <> 0  '+
                                ' BEGIN '+
                                ' INSERT  INTO TBL_MUSTERI VALUES (@KOD,@AD,@TUTAR) '+
                                ' SET @KOD=@@IDENTITY  '+
                                ' END '+
                                ' ELSE '+
                                ' BEGIN '+
                                ' UPDATE TBL_MUSTERI SET KOD=@KOD,AD=@AD,TUTAR=@TUTAR  '+
                                ' END '+
                                '	COMMIT TRANSACTION   '+
                                '	SELECT @KOD '+
                                ' RETURN '+
                                ' ERROR_HANDLER: '+
                                ' IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION  ';
                               // ' RETURN @ERROR ';

        ADOCommand1.Execute;
end;
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

SQL Kodlama

Mesaj gönderen sabanakman »

Bu iki kod arasında bazı farklar var (Delphi tarafında fazlalıklar). Mesela "Declare @ERROR INT" satırı ve "@ERROR" değişkenini kullanan "SET @ERROR = @@ERROR" satırlarının hiç bir işlevi yok. Birde en sonda bulunan "SELECT @KOD" satırının da bir işlevi yok. Muhtemelen bunlar denemeler yaparken kalmışlar. Aslında sorun yok gibi görünüyor ama bazı denemeler yaparsan belki düzelebilir.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
dynamo
Üye
Mesajlar: 96
Kayıt: 21 Haz 2005 02:05
Konum: istanbul

Mesaj gönderen dynamo »

delphi'deki fazla olan satırları --sürekli aynı hatayı verince --- sonradan
kendim ekledim.Tahminimce sorun:

Kod: Tümünü seç

' ERROR_HANDLER: '+
satırında.o yüzden " ERROR_HANDLER: " için
bu fazla tanımları yaptım.Query Analyzer'da oluşturup kullanabildiğim
kodun DELPHI karşılığı:

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject);
begin
       ADOCommand1.Cancel;
       ADOCommand1.CommandText :='CREATE PROCEDURE SP_MUSTERI_EKLE '+
                                '(@KOD   VARCHAR(20),'+
                                ' @AD  VARCHAR(20),'+
                                ' @TUTAR  MONEY)'+
                                ' AS'+
                                ' IF EXISTS(SELECT KOD FROM TBL_MUSTERI WHERE KOD=@KOD) '+
                                ' BEGIN  '+
                                ' RAISERROR(''Bu Kod Daha Önce Tanımlanmış.'',16,1) '+
                                ' RETURN  '+
                                ' END '+
                                ' IF @@ERROR <> 0 GOTO ERROR_HANDLER  '+
                                ' BEGIN TRANSACTION '+
                                ' IF @KOD <> 0  '+
                                ' BEGIN '+
                                ' INSERT  INTO TBL_MUSTERI VALUES (@KOD,@AD,@TUTAR) '+
                                ' SET @KOD=@@IDENTITY  '+
                                ' END '+
                                ' ELSE '+
                                ' BEGIN '+
                                ' UPDATE TBL_MUSTERI SET KOD=@KOD,AD=@AD,TUTAR=@TUTAR  '+
                                ' END '+
                                '	COMMIT TRANSACTION   '+
                                '	SELECT @KOD '+
                                ' RETURN '+
                                ' ERROR_HANDLER: '+
                                ' IF @@TRANCOUNT > 0 ROLLBACK TRAN  ';

        ADOCommand1.Execute;
end;
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Anlaşıldı

Mesaj gönderen sabanakman »

Delphi bileşenlerinden sorgular yazılırken ":" karakteri parametre belirtmek için kullanılır. Onun için bu sorguyu hiç bir Query ile yazamazsın. Bunun yerine ADOCommand1'in bağlı olduğu ADOConnection nesnesi ADOConnection1 olduğunu varsayarsak

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject); 
begin 
       ADOConnection1.Execute('CREATE PROCEDURE SP_MUSTERI_EKLE '+ 
                                '(@KOD   VARCHAR(20),'+ 
                                ' @AD  VARCHAR(20),'+ 
                                ' @TUTAR  MONEY)'+ 
                                ' AS'+ 
                                ' IF EXISTS(SELECT KOD FROM TBL_MUSTERI WHERE KOD=@KOD) '+ 
                                ' BEGIN  '+ 
                                ' RAISERROR(''Bu Kod Daha Önce Tanımlanmış.'',16,1) '+ 
                                ' RETURN  '+ 
                                ' END '+ 
                                ' IF @@ERROR <> 0 GOTO ERROR_HANDLER  '+ 
                                ' BEGIN TRANSACTION '+ 
                                ' IF @KOD <> 0  '+ 
                                ' BEGIN '+ 
                                ' INSERT  INTO TBL_MUSTERI VALUES (@KOD,@AD,@TUTAR) '+ 
                                ' SET @KOD=@@IDENTITY  '+ 
                                ' END '+ 
                                ' ELSE '+ 
                                ' BEGIN '+ 
                                ' UPDATE TBL_MUSTERI SET KOD=@KOD,AD=@AD,TUTAR=@TUTAR  '+ 
                                ' END '+ 
                                '   COMMIT TRANSACTION   '+ 
                                '   SELECT @KOD '+ 
                                ' RETURN '+ 
                                ' ERROR_HANDLER: '+ 
                                ' IF @@TRANCOUNT > 0 ROLLBACK TRAN  ');
end; 
şeklinde denemelisin. Eğer ADOConnection nesnesi kullanmayıp ConnectionString vererek çalışıyorsan o zaman bu ADOCommand bileşenini ADOConnection1 nesnesine bağlayıp bu ADOConnection1 nesnesinin ConnectionString değerini ayarlamalısın. Kodu uygulamalı olarak deneyemedim ama çalışacağından umutluyum. Sonucu gönderirsen sevinirim. Kolay gelsin.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
dynamo
Üye
Mesajlar: 96
Kayıt: 21 Haz 2005 02:05
Konum: istanbul

Mesaj gönderen dynamo »

şaban bey,dediğin gibi sorun çıkaran ":" karakteridir.ADOCommand,
ADOQuery ile denedim sonuç değişmedi.En son yazmış olduğun
ADOConnection nesnesi ile
ADOConnection1.Execute('')
içine alıp çalıştırdım şu hata mesajını verdi:
"There is already an object name 'SP_MUSTERI_EKLE' in database."
ilgili veritabanının önceden bu adlı sp olmadığı halde varmış gibi
mesaj veriyor.
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Farklı bir isimle kaydetmeye çalışsaydınız :wink:
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Kontrollü ekleme

Mesaj gönderen sabanakman »

O zaman yoksa prosedür oluşturulsun istersen şu şekilde yazmalısın.

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject); 
begin 
  ADOConnection1.Execute('if not exists (select * from dbo.sysobjects '+
    'where id = object_id(N''[dbo].[SP_MUSTERI_EKLE]'') and '+
    'OBJECTPROPERTY(id, N''IsProcedure'') = 1)'+
    'CREATE PROCEDURE SP_MUSTERI_EKLE '+ 
                                '(@KOD   VARCHAR(20),'+       
    .
    .
    .
veya varsa silip yenisini yazsın istersende şu şekilde olabilir.

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject); 
begin 
  ADOConnection1.Execute('if exists (select * from dbo.sysobjects '+
    'where id = object_id(N''[dbo].[SP_MUSTERI_EKLE]'') and '+
    'OBJECTPROPERTY(id, N''IsProcedure'') = 1)'+
    'drop procedure [dbo].[SP_MUSTERI_EKLE]';//<-varsa silinir...
////////////////
    ADOConnection1.Execute('CREATE PROCEDURE SP_MUSTERI_EKLE '+ 
                                '(@KOD   VARCHAR(20),'+       
    .
    .
    .
kodları test etmedim ama yaklaşık olarak böyle olacak.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
dynamo
Üye
Mesajlar: 96
Kayıt: 21 Haz 2005 02:05
Konum: istanbul

Mesaj gönderen dynamo »

ilk yönteminizde "incorrect syntax near the keyword 'PROCEDURE' "hatası verdi.

2.yönteminizde sorunsuz bir şekilde oluşturabildim...Çok TŞKR.... :D

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject); 
begin
        ADOConnection1.Execute('if exists (select * from dbo.sysobjects '+ 
             'where id = object_id(N''[dbo].[SP_MUSTERI_EKLE]'') and '+
             'OBJECTPROPERTY(id, N''IsProcedure'') = 1)'+
             'drop procedure [dbo].[SP_MUSTERI_EKLE]');//<-varsa silinir...
        ADOConnection1.Execute('CREATE PROCEDURE SP_MUSTERI_EKLE '+
                                '(@KOD   VARCHAR(20),'+
                                ' @AD  VARCHAR(20),'+
                                ' @TUTAR  MONEY)'+
                                ' AS'+
                                ' IF EXISTS(SELECT KOD FROM TBL_MUSTERI WHERE KOD=@KOD) '+ 
                                ' BEGIN  '+
                                ' RAISERROR(''Bu Kod Daha Önce Tanımlanmış.'',16,1) '+ 
                                ' RETURN  '+
                                ' END '+ 
                                ' IF @@ERROR <> 0 GOTO ERROR_HANDLER  '+
                                ' BEGIN TRANSACTION '+ 
                                ' IF @KOD <> 0  '+ 
                                ' BEGIN '+
                                ' INSERT  INTO TBL_MUSTERI VALUES (@KOD,@AD,@TUTAR) '+ 
                                ' SET @KOD=@@IDENTITY  '+
                                ' END '+ 
                                ' ELSE '+
                                ' BEGIN '+ 
                                ' UPDATE TBL_MUSTERI SET KOD=@KOD,AD=@AD,TUTAR=@TUTAR  '+
                                ' END '+
                                '   COMMIT TRANSACTION   '+ 
                                '   SELECT @KOD '+
                                ' RETURN '+
                                ' ERROR_HANDLER: '+
                                ' IF @@TRANCOUNT > 0 ROLLBACK TRAN  ');

end;
sp'yi enterprise manager->sored procedures'te açtığımda tüm
kodu tek bir satırda yazıyor.query analyzer'da oluşturduğum gibi satırları alt alta uygun boşluklar olacak şekilde sp'yi nasıl oluşturabilirim?
haliyle 500-600 satırlık bir kodun tek satırda oluşturulması kodun okunurluğunu ve anlaşılmasını zorlaştırır...

2.sorum:sp'yi delphi'de ADOStoredProc ile mi kullanmak avantajlı yada ADOCommand ile mi?.ikisi arasındaki fark tam olrak nedir?

ADOStoredProc ile kullanımı:

Kod: Tümünü seç

procedure Tfrmgiris.Button3Click(Sender: TObject);
begin
  ADOStoredProc1.Parameters.Clear;
  ADOStoredProc1.Parameters.AddParameter.Name:='@KOD';
  ADOStoredProc1.Parameters.ParamByName('@KOD').DataType:=ftString;
  ADOStoredProc1.Parameters.ParamByName('@KOD').Direction:=pdInput;
  ADOStoredProc1.Parameters.ParamByName('@KOD').Size:=20;

  ADOStoredProc1.Parameters.AddParameter.Name:='@AD';
  ADOStoredProc1.Parameters.ParamByName('@AD').DataType:=ftString;
  ADOStoredProc1.Parameters.ParamByName('@AD').Direction:=pdInput;
  ADOStoredProc1.Parameters.ParamByName('@AD').Size:=20;

  ADOStoredProc1.Parameters.AddParameter.Name:='@TUTAR';
  ADOStoredProc1.Parameters.ParamByName('@TUTAR').DataType:=ftBCD;
  ADOStoredProc1.Parameters.ParamByName('@TUTAR').Direction:=pdInput;
  ADOStoredProc1.Parameters.ParamByName('@TUTAR').Size:=8;

  ADOStoredProc1.Active:=false;
  ADOStoredProc1.Parameters.ParamByName('@KOD').Value:=edit1.Text;
  ADOStoredProc1.Parameters.ParamByName('@AD').Value:=edit2.Text;
  ADOStoredProc1.Parameters.ParamByName('@TUTAR').Value:=edit3.Text;
  ADOStoredProc1.ExecProc;
end;
ADOCommand ile kullanımı:

Kod: Tümünü seç

procedure Tfrmgiris.Button4Click(Sender: TObject);
begin
   ADOCommand1.Cancel;
   ADOCommand1.CommandText:='EXEC SP_MUSTERI_EKLE @KOD ='''+edit1.Text+''' ,@AD ='''+edit2.Text+''' ,@TUTAR ='+edit3.Text+'';
   ADOCommand1.Execute;
end;
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

1. Her satırın bittiği yerde #13#10 string bilgisi olmalı.

Kod: Tümünü seç

procedure Tfrmgiris.Button1Click(Sender: TObject); 
const NL=#13#10;
begin 
        ADOConnection1.Execute('if exists (select * from dbo.sysobjects '+ 
             'where id = object_id(N''[dbo].[SP_MUSTERI_EKLE]'') and '+ 
             'OBJECTPROPERTY(id, N''IsProcedure'') = 1)'+
             'drop procedure [dbo].[SP_MUSTERI_EKLE]');//<-varsa silinir... 
        ADOConnection1.Execute('CREATE PROCEDURE SP_MUSTERI_EKLE '+NL+//<-yeni satır
                                '(@KOD   VARCHAR(20),'+NL+//<-yeni satır
                                ' @AD  VARCHAR(20),'+NL+
                                ' @TUTAR  MONEY)'+NL+
                                ' AS'+NL+
                                ' IF EXISTS(SELECT KOD FROM TBL_MUSTERI WHERE KOD=@KOD) '+NL+
  .
  .
  . 
2.Eğer amacına ulaşıyorsan bunun pek bir önemi yok ama procedure için ayrı bir bileşen yazılmışsa bunun bir avantajı vardır muhakkak.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Cevapla