Re: SqlDataAdapter1.SelectCommand.CommandType= CommandType.StoredProcedure

From: Elmar Boye (ElmarB_at_gmx.net)
Date: 02/13/05


Date: Sun, 13 Feb 2005 21:44:41 +0100


Hallo Klaus,

Klaus Eckert <a@eckert-k.de> schrieb ...
> "Elmar Boye" ElmarB@gmx.net> schrieb ...
>> Klaus Eckert <a@eckert-k.de> schrieb ...
>>> bei der Einstellung SQLDataAdapter.CommandType.StoredProcedure
>>> kann man beim EXEC PROC keine Parameter beifügen.
>>
>> das EXEC ist überflüssig und schädlich...
>>
>>> Statt dessen muss CommandType.Text eingestellt werden.
>>
>> ... wenn Du nur den qualifizierten Prozedurnamen
>> (Besitzer.ProzedurName) im CommandText abstellst, so wäre das der
>> richtige Weg,
>> mit und ohne Parameter.
> die ich leider nicht ganz verstanden habe.
>
> M.E.widersprechen sich Deine Antworten 1 u.2.
>
> 1)
>> ... wenn Du nur den qualifizierten Prozedurnamen
>> (Besitzer.ProzedurName)
>
>> im CommandText abstellst, so wäre das der richtige Weg,
>> mit und ohne Parameter.

Das soll heissen:
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "sp_ABC";

wobei besser ist immer mit dem Besitzer der Prozedur zu
qualifizieren, also
    command.CommandText = "dbo.sp_ABC";

Ausserdem sollten Standardprozeduren nie das Präfix "sp_"
haben, da dies für Systemprozeduren reserviert ist,
und diese zunächst in der master Datenbank gesucht werden.
Die Gründe siehe "Erstellen einer gespeicherten Prozedur"
in der SQL Server Dokumentation.

> 2)
>>> oder ist es vernünftig, generell CommandType.Text
>>> einzustellen, auch wenn keine Parameter beigefügt werden?
>
>> Nein - siehe oben.

>
> Um es noch mal klar zu sagen, ich spreche nur von Procedur-Aufrufen
> mit den Fällen mit oder ohne beigegefügte Parameter.

    command.CommandType = CommandType.Text;
    command.CommandText = "EXEC sp_ABC ...";
(... für die optionalen Parameter) war damit nicht gemeint.

Das ist zwar möglich aber auch nur so, da der SQL Text so nie
beim Client interpretiert wird, sondern erst im Nachhinein
vom SQL Server (also mit serverseitigem Aufwand verbunden).

> Bei Einstellung "CommandType.StoredProcedure" erhalte ich nach
> Aufruf einer Proc mit Parameter die Fehlermeldung
> "Die gespeicherte Procedur sp_ABC @Pro='ProjectA' konnte nicht
> gefunden werden.".

Bei CommandType.StoredProcedure darf ausschliesslich der (qualifizierte)
Prozedurname im CommandText stehen und weder EXEC noch zusätzlicher
Text angegeben werden. Also anhand Deines Beispiels,
zur Verdeutlichung in epischer Länge, kann u. U. verkürtzt werden:
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "dbo.sp_ABC";
    parameter = new SqlParameter();
    parameter.Name = "@Pro",
    parameter.SqlDbType = SqlDbType.VarChar;
    parameter.Length = 40;
    parameter.Value = "ProjectA";
    command.Parameters.Add(parameter);

> Dagegen erfolgt der genannte Aufruf mit "CommandType.Text"
> problemlos.

siehe obige Klarstellung zu 2).

Wobei ich das "problemlos" in grosse Fragezeichen setzen würde.
Das gilt nur solange, wie Dir nicht Unicode, Parameterlänge
und/oder interne Konvertierung einen Strich durch die Rechnung
macht. Plus potentieller SQL Injection wenn die Parameterwerte
von ausserhalb kommen. Kurzanmerkungen zu den einzelnen Punkten:

Zu Unicode: Du übergibst 'ProjectA' und das bedeutet eine ANSI
Parameterangabe, wohingegen Du (wir sind schliesslich in .NET)
im CommandText Unicode übergibst. Wenn nun aber ein Zeichen
drin ist, was nicht in der eingestellten ANSI-Codepage drin ist,
gibts Probleme.
Zur Länge: Da Du keine Länge vorgibst, wird erst beim Server
geprüft, ob das was abgeschnitten werden könnte und ggf.
entsprechend reagiert (siehe SET ANSI_WARNINGS).
Zur Konvertierung: Alle Parameter werden erst beim Server
entsprechend SQL Server Regelung konvertiert, siehe
CAST/CONVERT und "Rangfolge der Datentypen" in der
SQL Server Dokumentation.

Zu SQL Injection und einigem ergänzend mehr siehe auch:
http://www.microsoft.com/germany/technet/datenbank/articles/600213.mspx
(dort als SQL-Skriptinjektion übersetzt)

Wenn Dir das alles nichts ausmacht, darfst Du CommandType.Text
und selbstgebasteltes EXEC ... mit/ohne Parameter verwenden.

Gruss
Elmar



Relevant Pages

  • Re: Best Way to Test Against a Database
    ... that I have my CommandText, ... If your database client library (and the server) supports the concept of "prepared" statements, this would be a very easy way to verify the correctness of the SQL statements without actually executing the command. ... "Preparing" a statement will send the SQL to the server and the server can use the SQL to build a query plan. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Best Way to Test Against a Database
    ... that I have my CommandText, ... "Preparing" a statement will send the SQL to the server and the ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Master/Detail with ADODatasets (again)
    ... So that means the SQL statements use to retrieve data from the ... I just set the CommandText in Patients to 'Select ... then save it back to the server before moving on to the ...
    (borland.public.delphi.database.ado)

Loading