Start
Unternehmen
ERP / PPS / Prozesse
Business Intelligence
Server-Technologien
Software-Technologien
Technologie-Beratung
Individual-Software
Produkte

Comelio GmbH
Rellinghauser Straße 10
D-45128 Essen
Deutschland
Fon: 0201-437517-0
Fax: 0201-437517-10
info@comelio.com

Comelio GmbH
Goethestraße 34
D-13086 Berlin
Deutschland
Fon: 030-921019-85
Fax: 030-921019-89
info@comelio.com

Comelio GmbH (Ecos)
Glockengießerwall 17
D-20095 Hamburg
Deutschland
Fon: 040-4689908-91
Fax: 040-4689908-95
info@comelio.com

Comelio GmbH (Ecos)
Mainzer Landstraße 27-31
D-60329 Frankfurt
Deutschland
Fon: 069-2475030-35
Fax: 069-2475030-39
info@comelio.com

Comelio GmbH (Ecos)
Stiglmaierplatz/Dachauer Str. 37
D-80335 München
Deutschland
Fon: 089-2000154-90
Fax: 089-2000154-94
info@comelio.com

Comelio GmbH (Ecos)
Liebknechtstr. 33
D-70565 Stuttgart
Deutschland
Fon: 0711-252534-20
Fax: 0711-252534-24
info@comelio.com

Comelio-Blog > MS SQL Server > Batch-Einsatz bei Webservices

Batch-Einsatz

Man kann einen Webservice verwenden, um Batch-Anweisungen, d.h. T-SQL-Anweisungen mit Abfragen und T-SQL-Programmen bzw. Prozedur-/Funktions-aufrufen zur Datenbank zu schicken. Dazu ist gar keine Funktion/Prozedur notwendig, die man als Operationen für den Webservice anbietet. Stattdessen richtet man nur den entsprechenden Dienst ein, der die Anweisungen in einem standardisierten SOAP-Format erwartet und die Ergebnisse wie Rückgabewerte oder Ergebnismengen in XML-Form zurückliefert.

Kontakt

Anrede* Herr Frau
Vorname*
Nachname*
Firma
E-Mail*
Tel-Nr.
Bereich*
Freitext

SQL-Batch-Anweisungen als Webservice

Für die Einrichtung eines Batch-Webservices ist nicht viel mehr zu tun als die Option BATCHES = ENABLED für einen Endpunkt freizugeben. Die Angabe von weiteren Operationen ist möglich, aber nicht notwendig, sodass sich die komplette Anweisung dieses Beispiels auf den schon bekannten CREATE ENDPOINT-Befehl reduziert.

CREATE ENDPOINT epEmployee 
STATE = STARTED
AS HTTP(
PATH = '/sql',
AUTHENTICATION = (INTEGRATED ),
PORTS = ( CLEAR ),
SITE = 'localhost'
)
FOR SOAP (
BATCHES = ENABLED,
WSDL = DEFAULT,
DATABASE = 'AdventureWorks',
NAMESPACE = 'http://Adventure-Works/Employees'
)

SOAP-Anfragen

Da für die Batch-Anweisungen nicht die Notwendigkeit besteht, Operationen anzulegen und XML Schema-Strukturen anzugeben, da ja ausschließlich die T-SQL-Anweisungen innerhalb der verschickten SOAP-Anfrage verarbeitet werden, stellt der MS SQL Server ein eigenes SOAP-Format zur Verfügung, mit dem diese Anweisungen verschickt werden können. Innerhalb des sqlbatch-Elements erwartet es die Anweisungen im Element BatchCommands. Sollten mehrere Anweisungen aufeinander folgen – was ja durchaus der Sinn und Zweck von Batch-Anweisungen ist -, dann trennt man sie durch ein Semikolon. Es ist darüber hinaus zulässig, Parameter zu verwenden, die innerhalb der Anweisungen wie gewöhnliche Variablen mit dem @-Zeichen ausgezeichnet werden. Diese definiert man dann im Parameters-Element, das den Anweisungen folgt. Jeder Parameter erhält hier ein eigenes SqlParameter-Kindelement, in dem in einer umfassenden Reihe von Attributen die Datentypeigenschaften definiert werden. Der eigentliche Wert befindet sich dann im Element Value, welches nicht als Attribut modelliert wurde, da ja auch XML-Daten übertragen werden könnte.

<SOAP-ENV:Body>
<ms:sqlbatch xmlns:ms="http://schemas.microsoft.com/
sqlserver/2004/SOAP">
<ms:BatchCommands>SELECT emp.EmployeeID AS "@Emp-ID",
emp.Title AS "Name/@Title",
FirstName AS "Name/FirstName",
LastName AS "Name/LastName",
...
FROM ...
WHERE emp.EmployeeID = @x
FOR XML PATH, ROOT('Emp-List');</ms:BatchCommands>
<ms:Parameters>
<sp:SqlParameter name="x" sqlDbType="Int" direction="Input" maxLength="1" precision="18" scale="0" sqlCompareOptions="Default" localeId="-1" sqlCollationVersion="0" sqlSortId="0">
<sp:Value>17</sp:Value>
</sp:SqlParameter>
</ms:Parameters>
</ms:sqlbatch>
</SOAP-ENV:Body>

Als Ergebnis erhält man ein ebenfalls vom MS SQL Server vordefiniertes SOAP-Format. Innerhalb von sqlbatchResponse/sqlbatchResult befinden sich XML-Ergebnisse genauso wie relationale Ergebnismengen oder sonstige Datentypen. Sie werden über verschiedene Datentypen, die in verschiedenen Elementen/Attributen definiert werden vorab ausgezeichnet, sodass man die unterschiedlichen möglichen Datentypen genau erkennen kann. Im vorliegenden Beispiel wurde eine FOR XML-Abfrage zur Datenbank geschickt, die auch tatsächlich zu einer XML-Ausgabe führt. Daher lautet hier die Zuordnung zum Datentyp SqlXml.

<SOAP-ENV:Body>
<sql:sqlbatchResponse>
<sql:sqlbatchResult xmlns="">
<sqlresultstream:SqlXml xsi:type="sqlsoaptypes: ">
<SqlXml>
<Emp-List>
<row Emp-ID="17">
<Name Title="Production Technician - WC10">
<FirstName>Doris</FirstName>
<LastName>Hartwig</LastName>
</Name> ...
</row>
</Emp-List>
</SqlXml>
</sqlresultstream:SqlXml>
<sqlresultstream:SqlRowCount xsi:type="sqlrowcount:
SqlRowCount">
<sqlrowcount:Count>1</sqlrowcount:Count>
</sqlresultstream:SqlRowCount>
</sql:sqlbatchResult>
</sql:sqlbatchResponse>
</SOAP-ENV:Body>

In der zweiten Anfrage anfrage2.xml verzichtet man ganz einfach auf die FOR XML-Klausel und erhält stattdessen das relationale Ergebnis in XML-Format aufbereitet zurück. Dies ist natürlich der Standardfall, wenn beliebige SELECT-Anfragen an die Datenbank gestellt werden.

<SOAP-ENV:Body>
<sql:sqlbatchResponse>
<sql:sqlbatchResult xmlns="">
<sqlresultstream:SqlRowSet
msdata:UseDataSetSchemaOnly="true"
msdata:UDTColumnValueWrapped="true">
<xsd:schema>
<xsd:simpleType name="int">
<xsd:restriction base="xsd:int"/>
</xsd:simpleType>
<!-- Weitere verwendete Datentypen in XML Schema-Notation -->
</xsd:schema>
<xsd:schema Namensräume...>
<xsd:element name="SqlRowSet1"
msdata:IsDataSet="true"
msdata:DataSetName="SqlDataSet">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="row" minOccurs="0"
maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EmpID"
type="sqltypes:int"/>
<!-- Weitere Ergebnis-Elemente in XML Schema-Notation-->
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<diffgr:diffgram>
<SqlRowSet1>
<row>
<EmpID>17</EmpID>
<Title>Production Technician - WC10</Title>
<!-- Weitere SQL-Ergebnisse in XML-Format -->
</row>
</SqlRowSet1>
</diffgr:diffgram>
</sqlresultstream:SqlRowSet>
<sqlresultstream:SqlRowCount>
<sqlrowcount:Count>1</sqlrowcount:Count>
</sqlresultstream:SqlRowCount>
</sql:sqlbatchResult>
</sql:sqlbatchResponse>
</SOAP-ENV:Body>

Um zu zeigen, dass man auch mehrere Anweisungen zur Datenbank schicken kann, die insgesamt auch mehr als einen Parameter verwenden, folgt noch ein Beispiel, in dem zwei verschiedene Abfragen enthalten sind. Beide fordern unterschiedliche relationale Ergebnismengen an.

<ms:sqlbatch>
<ms:BatchCommands>SELECT EmployeeID, Title, ...
FROM HumanResources.Employee
WHERE EmployeeID = @x;
SELECT COUNT(*)
FROM HumanResources.Employee;</ms:BatchCommands>
<ms:Parameters>
<sp:SqlParameter name="x"
sqlDbType="Int" direction="Input">
<sp:Value>17</sp:Value>
</sp:SqlParameter>
</ms:Parameters>
</ms:sqlbatch>

In diesem Fall erhält man zwei verschiedene Ergebnismengen, die sich auch namentlich unterscheiden: SqlRowSet1 und SqlRowSet2. Die relationale Ergebnismenge, die eine gewöhnliche Abfrage darstellt, enthält wiederum die Spaltennamen als Elementnamen und (hier nicht abgedruckt) XML Schema-Erläuterungen zu den einzelnen Spalten. Die Aggregatabfrage, die keinen Aliasnamen für die Aggregatspalte verwendete, enthält an gleicher Stelle den Standardspaltennamen Column.

<sql:sqlbatchResponse>
<SqlRowSet1>
<row>
<EmployeeID>17</EmployeeID>
<Title>Production Technician - WC10</Title>
</row>
</SqlRowSet1>
<SqlRowSet2>
<row>
<Column1>290</Column1>
</row>
</SqlRowSet2>
</sql:sqlbatchResponse>

Ein Klient in .NET

Für den Batch-Webservice soll auch ein .NET-Klient erstellt werden. Die Beschreibung des Dienstes, die im Visual Studio im Assistenten, mit dem man Webverweise hinzufügt, angezeigt wird, lautet: sqlbatch (BatchCommands As string , Parameters As ArrayOfSqlParameter) As SqlResultStream. Vom dem Stellvertreter-Objekt ruft man die Methode sqlbatch() ab und übergibt ihr im ersten Parameter eine Zeichenkette mit allen T-SQL-Anweisungen, die ausgeführt werden sollen, und im zweiten Parameter ein per Referenz übergebenes Array mit den in den T-SQL-Anweisungen verwendeten Parametern. Die Parameter erstellt man in einzelnen SqlParameter-Objekten, die als Eigenschaften die schon in der SOAP-Datei gesehenen Werte wie Name, Datentypzuordnung, Wert, Präzision und Genauigkeit erwarten. Wie auch schon in der SOAP-Antwort-Datei gesehen, kann es bei mehreren Anweisungen auch mehrere Ergebnismengen geben, die in einzelnen DataSet-Objekten abgerufen werden können. Sie werden im nachfolgenden Beispiel in einzelne XML-Dateien gespeichert, um zu zeigen, wie im DataSet-Objekt XML Schema und XML aufgebaut ist.

// Parameterwert abfragen
Console.WriteLine("Geben Sie eine Mitarbeiternummer ein: ");
string employeeId = Console.ReadLine();
// Stellvertreter-Objekt für Webservice erstellen
epEmployee proxy = new epEmployee();
proxy.Credentials = System.Net.CredentialCache.
DefaultCredentials;
// Webservice nutzen
try {
// Parameter in SQL-Anweisung ankündigen
SqlParameter param = new SqlParameter();
param.name = "x";
param.sqlDbType = sqlDbTypeEnum.Int;
param.Value = employeeId;
param.direction = ConsoleApplication1.localhost.
ParameterDirection.Input;
SqlParameter[] queryParams = new SqlParameter[] { param };
// SQL-Anweisungen sammeln
string sql = "SELECT COUNT(*) AS Anzahl
FROM HumanResources.Employee;"
+ "SELECT * FROM HumanResources.Employee
WHERE EmployeeID = @x";
// Webservice verwenden
object[] results = proxy.sqlbatch(sql, ref queryParams);
// Objekte/Variablen für Ergebnisse
DataSet ds = null;
long rowCount = 0;
string message = string.Empty;
int i = 1;
// Objekte der Ergebnismenge untersuchen
foreach (object o in results){
if (o is DataSet){
ds = (DataSet)o;
ds.WriteXmlSchema("c:/schema" + i + ".xsd");
ds.WriteXml("c:/xml" + i + ".xml");
i++;
}
else if (o is SqlRowCount)
rowCount = ((SqlRowCount)o).Count;
else if (o is SqlMessage)
message = ((SqlMessage)o).Message;
Console.WriteLine("Reihen: " + rowCount
+ " Nachricht: " + message);
}...

Die nachfolgende Abbildung zeigt die Ausgabe der auf der Festplatte durch den Dienst erstellten XML-/XML Schema-Dateien. Die einzelnen Reihen speichert das DataSet in row-Elementen, welche wiederum in einem SqlDataSet-Wurzelelement gespeichert sind. Als Spaltennamen kommen die tatsächlichen Spaltennamen, Aliasnamen oder automatisch erzeugte Spaltennamen zum Einsatz.

    Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik Comelio GmbH MS SQL Server: Batch-Einsatz von Webservices - T-SQL XML Webservices Programmierung Bücher Anleitung Tutorial Skulschus Wiederstein Kozik
Seminare