Index Server: Eine ausführliche Anleitung mit effektiven Verfahren und Methoden für das Indizieren Mit Microsoft® Index Server können Sie Volltextsuchen vornehmen und alle Arten von Informationen aus einem beliebigen Webbrowser in praktisch allen möglichen Formaten einfach mit einem Mausklick abrufen. Indizierung Erteilen interaktiver Anmelderechte Indizieren von SQL Server Die Tipps in diesem Abschnitt enthalten Informationen zum weiteren Verfeinern von Abfragen, damit genau das zurückgegeben wird, wonach Sie suchen. Zusammengesetzte Wörter Wenn bei der Abfrage alle Variationen eines zusammengesetzten Wortes gefunden werden sollen, geben Sie das Wort mit Bindestrichen ein. Ein gängiges Beispiel hierfür ist Datenbank, die Zusammensetzung von Daten und Bank. Die Schreibweise von zusammengesetzten Wörtern ist häufig uneinheitlich, so dass sowohl Daten Bank als auch Daten-Bank im Text vorkommen kann. Wenn Sie Daten-Bank eingeben, sucht Index Server nach allen Instanzen von Daten-Bank, Daten Bank und Datenbank. Eigenschaftenabfragen Wenn Sie in der IDQ-Datei die CiForceUseCi-Variable auf TRUE einstellen, ändert sich das Verhalten einiger Eigenschaftenabfragen mit regulären Ausdrücken. Beispiel: Wenn die Datei Ciquery.htm indiziert wurde, gibt Index Server z. B. für folgende Abfragen Treffer zurück: #filename ciquery.htm #filename *.htm #filename ciquery* Für die FileName-Eigenschaft wird sowohl der Dateiname als auch der umgekehrte Dateiname im Inhaltsindex gespeichert. Der umgekehrte Dateiname wird zum Auflösen der Abfrage #filename *.htm benötigt, da der Inhaltsindex Präfixe, nicht aber Suffixe, abgleichen kann. Wenn die Datei Test.doc indiziert wurde, gibt Index Server Treffer für Abfragen zurück wie z. B. #doctitle test* und #doctitle test.doc, nicht aber für die Abfrage #doctitle *.doc. Siehe DocTitle auf der Seite "Abfragesprache". Vpath wird (ebenso wie Path und Characterization) nicht im Inhaltsindex gespeichert. Wenn CiForceUseCi auf TRUE festgelegt wird, gibt Index Server daher für Abfragen wie die Folgenden keine Treffer zurück, selbst wenn Test.doc indiziert wurde. #vpath /test.doc #vpath /tes* Indizierung Seiten, auf die kürzlich zugegriffen wurde In vielen Fällen suchen Sie mit Ihrem Browser nach kürzlich angezeigten Informationen. Wenn Sie denken: "Ich weiß genau, dass ich mir diese Seite erst vor kurzem angesehen habe...", dann ist folgender Trick möglicherweise hilfreich: Wenn Index Server auf dem gleichen Computer wie der Browser ausgeführt wird (z. B. auf einer Microsoft Windows NT®-Arbeitsstation mit Peerwebdiensten), können Sie für den Cacheordner des Browsers ein virtuelles Verzeichnis erstellen. In diesem Fall werden Seiten auf die Sie im Intranet oder Internet zugreifen automatisch von Index Server indiziert. Beim Übertragen von Abfragen werden die Seiten zurückgegeben, auf die Sie kürzlich zugegriffen haben. Bei den Verweisen auf die Seiten handelt es sich nicht um Verweise auf die tatsächlichen Seiten im Web, sondern auf die im Browsercache zwischengespeicherten Seiten. Das ist normalerweise kein großes Problem, weil Sie sich in den meisten Fällen beim Anblick der Seite wieder erinnern können. Außerdem enthalten zwischengespeicherte Seiten häufig Verknüpfungen zur Originalsite. Protokolleinträge Durch den vorangegangenen Trick sollte es wesentlich einfacher sein, in den IIS-Protokollen fündig zu werden. Erstellen Sie einfach ein virtuelles Verzeichnis für das Verzeichnis mit den IIS-Protokollen. Index Server indiziert die Protokolle mit Hilfe des Textfilters. Damit können Sie Abfragen für Protokolleinträge übertragen und die Einträge schnell mit der Hervorhebungsfunktion von Index Server 2.0 finden. Da Index Server alle Abfragen protokolliert, können Sie sogar nach Wörtern und Begriffen suchen, nach denen andere Benutzer suchen. Nicht lateinische Zeichen Wenn in einer Gruppe von Dokumenten nach nicht lateinischen Zeichen, z. B. kyrillischen Zeichen, gesucht werden soll, muss die Einstellung für das Gebietsschema in der IDQ-Datei mit der Einstellung für das Gebietsschema des Servers übereinstimmen. Geben Sie den Code RU ein, um z. B. CiLocale in der IDQ-Datei auf Russisch einzustellen. Sie können stattdessen auch das Kennzeichen HTTP_ACCEPT_LANGUAGE in Ihrem Browser auf Russisch einstellen. Tabelle mit Basiszeichensätzen, Anzeigenamen und Aliasen Beim Identifizieren der Codeseite einer HTML-Datei sucht der HTML-Filter nach einem Metatag, der den Zeichensatz der Seite einstellt. Der folgende Metatag legt fest, dass die HTML-Seite die Windows-Codeseite 1252 verwendet. <meta http-equiv="Content-Type" content="text/html; charset= Windows-1252"> Wenn eine Codeseite festgelegt wurde, verwendet der HTML-Filter diese, um die MehrbyteZeichenkodierung in Unicode umzuwandeln. In der folgenden Tabelle wird unter "Basiszeichensatz" die grundlegende Umwandlungssoftware aufgeführt, die in Microsoft® Internet Explorer Version 3.0 integriert oder als Langpack erhältlich ist. In der Spalte "Aliase" werden die IDs aller anderen, erkannten Zeichensätze aufgeführt. Sie kann mit Hilfe der Umwandlungsmethode für Basiszeichensätze ohne Umwandlung repräsentiert werden. Dies bedeutet aber nicht, dass Aliase und Basiszeichensatz den gleichen Zeichensatz repräsentieren, sondern dass der Aliaszeichensatz einen untergeordneten Zeichensatz des Basiszeichensatz darstellen kann. Der Basiszeichensatz ist kein anerkannter Name, solange er nicht in der Spalte "Aliase" wiederholt wird. Die Spalte "Anzeigename" repräsentiert den Namen dieses Zeichensatzes in der Benutzeroberfläche von Internet Explorer und müsste daher lokalisierbar sein. Basiszeichensatz Anzeigename 1252 Westeuropa 28592 Mitteleuropäisch (ISO) Aliase (Zeichensatz-IDs) us-ascii, iso8859-1, ascii, iso_8859-1, iso-8859-1, ANSI_X3.4-1968, iso-ir-6, ANSI_X3.4-1986, ISO_646.irv:1991, ISO646-US, us, IBM367, cp367, csASCII, latin1, iso_8859-1:1987, iso-ir-100, ibm819, cp819, Windows-1252 iso8859-2, iso-8859-2, iso_8859-2, latin2, iso_88592:1987, iso-ir-101, l2, csISOLatin2 1250 1251 1253 1254 932 EUC-JP JIS 1257 950 Mitteleuropäisch (Windows) Kyrillisch (Windows) Griechisch (Windows) Türkisch (Windows) Shift-JIS EUC JIS 949 Chinesisch (traditionell) (BIG5) Chinesisch (vereinfacht) Kyrillisch (KOI8R) Koreanisch 1255 Hebräisch 1256 874 1258 Arabisch Thai Vietnamesisch 936 20866 Windows-1250, x-cp1250 Windows-1251, x-cp1251 Windows-1253 Windows-1254 shift_jis, x-sjis, ms_Kanji, csShiftJIS Extended_UNIX_Code_Packed_Format_for_Japanese, csEUCPkdFmtJapanese, x-euc-jp csISO2022JP, iso-2022-jp Windows-1257 big5, csbig5, x-x-big5 GB_2312-80, iso-ir-58, chinesisch, csISO58GB231280, csGB2312, gb2312 csKOI8R, koi8-r ks_c_5601, ks_c_5601-1987, koreanisch, csKSC56011987 In Internet Explorer Version 3.0a wurde Folgendes hinzugefügt: BasisAnzeigename Aliase (Zeichensatz-IDs) zeichensatz ISO_8859-8:1988, iso-ir-138, ISO_8859-8, ISO-8859-8, hebräisch, csISOLatinHebrew Windows-1256 Windows-874 Windows-1258 In einer künftigen Version von Internet Explorer wird es auch folgenden Basiszeichensatz geben: Basiszeichens Anzeigename atz UNICODE Unicode UTF-8 Aliase (Zeichensatz-IDs) UTF-8, unicode-1-1-utf-8, unicode-2-0-utf-8 Erteilen interaktiver Anmelderechte In einigen Fällen benötigt ein Benutzer auf einem Computer möglicherweise interaktive Anmelderechte. So erteilen Sie diese Rechte 1. Öffnen Sie den Windows NT-Benutzer-Manager für Domänen auf Server A. 2. Wählen Sie in der Liste Benutzername die Benutzer-ID aus, der Sie Anmelderechte erteilen möchten. 3. Klicken Sie im Menü Richtlinien auf Benutzerrechte. 4. Klicken Sie auf den Pfeil neben dem Feld Recht im Dialogfeld Richtlinien für Benutzerrechte, und wählen Sie Lokale Anmeldung aus. Möglicherweise wird in der Liste Erteilen im Dialogfeld Richtlinien für Benutzerrechte kein Benutzername angezeigt. So fügen Sie den Benutzer hinzu 1. Klicken Sie auf Hinzufügen. 2. Klicken Sie auf den Pfeil neben der Liste Namen anzeigen von, und wählen Sie die Domäne aus, in der interaktive Anmelderechte erteilt werden sollen. 3. Klicken Sie auf Benutzer anzeigen. 4. Wählen Sie den Benutzer aus der Liste Namen aus, und klicken Sie auf Hinzufügen. 5. Klicken Sie auf OK. 6. Stellen Sie sicher, dass der Benutzer in der Liste Erteilen im Dialogfeld Richtlinien für Benutzerrechte angezeigt wird. 7. Klicken Sie auf OK. Indizieren von SQL Server Neben der Suche nach Text in verschiedenen Formaten kann Index Server des Weiteren in Tabellen nach webbasierten Textdaten suchen, die mit dem relationalen Datenbank-Verwaltungssystem Microsoft® SQL Server 6.5 formatiert wurden. Auf dieser Seite werden zwei Beispiele vorgestellt: Beispiel 1: Stores-Tabelle Beispiel 2: Pub_Info-Tabelle SQL Server enthält die gespeicherte Prozedur sp_makewebtask. Diese gespeicherte Prozedur exportiert SQL Server-Daten als Webseiten. Durch Kombinieren von benutzerdefinierten gespeicherten Prozeduren und Triggern ist es möglich, für jeden in einer SQL Server-Tabelle enthaltenen Datensatz eine Webseite zu generieren und die Webseiten anschließend mit Index Server zu indizieren. Wie Sie dabei vorgehen, ist aus dem folgenden Verfahren ersichtlich: 1. Wählen Sie ein Verzeichnis aus, auf das Index Server zugreifen kann. In diesem Verzeichnis werden die aus der SQL Server-Tabelle generierten Seiten gespeichert. In "Beispiel 1: Stores-Tabelle" werden Webseiten im Verzeichnis D:\Sql_web\Pubs\Stores generiert. 2. Erstellen Sie ein virtuelles Verzeichnis, das dem in Schritt 1 ausgewählten Verzeichnis entspricht. Erstellen Sie für beide Beispiele das virtuelle Verzeichnis /pubs, und verweisen Sie in diesem auf das Verzeichnis D:\Sql_web\Pubs. 3. Erstellen Sie eine gespeicherte Prozedur, die pro Datensatz eine HTML-Seite generiert. Der primäre Schlüsselwert des Datensatzes wird im Namen der generierten HTMLSeite verwendet, um eine 1:1-Zuordnung zwischen einem Datensatz und einer HTML-Seite zu gewährleisten. 4. Erstellen Sie eine IDC-Datei, um für alle Tabellenzeilen Webseiten zu generieren. Sie können diese einmal am Anfang oder in regelmäßigen Abständen ausführen, um für alle Datensätze in der Tabelle Webseiten zu generieren. Anmerkung Beim Code in den Beispielen wird davon ausgegangen, dass der Verzeichnispfad weniger als 100 Zeichen umfasst. Bei Pfaden mit über 100 Zeichen müssen Sie die Parameter in den gespeicherten Prozeduren erhöhen. Folgende Schritte sind optional: 1. Erstellen Sie einen INSERT/UPDATE-Trigger für die Tabelle. Dieser Trigger ruft die erstellte gespeicherte Prozedur mit den richtigen Parametern auf. Trigger sind nur nötig, wenn Webseiten automatisch bei Tabellenaktualisierungen generiert werden sollen. Wenn Sie stattdessen zum Generieren der Seiten lieber regelmäßig einen Batchbefehl ausführen, sind Trigger nicht notwendig. 2. Erstellen Sie einen DELETE-Trigger für die Tabelle. Dieser Trigger löscht die Webseite, die zu dem gelöschten Datensatz gehört. 3. Erstellen Sie eine Vorlagendatei, um das Layout der generierten Webseiten zu beschreiben. Die Vorlagendatei im Beispiel Stores-Tabelle heißt Stores.tpl. Vorbereitungen Damit Sie die beiden Beispiele verstehen, müssen Sie sich mit Folgendem auskennen: Der Transact-SQL-Sprache Den Operationen, den Programmen, den gespeicherten Prozeduren und den Triggern von SQL Server Der Syntax- und Parameterbeschreibung für die gespeicherte Prozedur sp_makewebtask IDC-Skriptdateien und HTX-Dateien Informationen zu den ersten drei Elementen finden Sie in der SQL Server Dokumentation und Informationen zu IDC- und HTX-Dateien in der IIS-Dokumentation. Wenn Sie sich mit allen Elementen in der Liste auskennen, müssen Sie Folgendes tun: 1. Den ODBC-Eintrag wie auf den Beispielseiten der IIS-Datenbank beschrieben einrichten Diese Beispiele verwenden außerdem den Web-SQL-System-DSN (Data Source Name). Nehmen Sie daher die notwendigen Änderungen an den folgenden Beispielen vor, wenn Folgendes auf Sie zutrifft: Der Standardkontonamen (sa) wurde geändert - oder Dem Web-SQL-System-DSN wurde ein Kennwort zugewiesen. Standardmäßig ist kein Kennwort zugewiesen. 2. Geben Sie alle SQL Server-Abfragen über das Programm ISQL/w aus, das zum Lieferumfang von SQL Server gehört. Beispiel 1: "Stores"-Tabelle Im ersten Beispiel wird die Stores-Tabelle in der pubs-Beispieldatenbank verwendet, die zum Lieferumfang von SQL Server gehört. Alle Spalten der Stores-Tabelle enthalten weniger als 255 Zeichen. Wenn eine Textspalte voraussichtlich mehr als 255 Zeichen enthält, müssen Sie etwas anders verfahren. Siehe dazu Beispiel 2: Pub_Info-Tabelle. Anmerkung Bei allen Anführungszeichen im Beispielcode handelt es sich um einfache Anführungszeichen (' '). Schema für die "Stores"-Tabelle Die folgende Tabelle zeigt das Schema der Stores-Tabelle: Spaltenname stor_id store_name store_address city state zip Datentyp char(4) varchar(40) varchar(40) varchar(20) char(2) char(5) Schlüssel/Index Primärschlüssel Da stor_id den Primärschlüssel darstellt, generieren Sie mit stor_id einen eindeutigen Dateinamen für jeden Datensatz in der Tabelle. Im Beispiel Stores-Tabelle rufen Sie nur stor_id, store_name und store_address ab. Darüber hinaus wird stor_id als Metaeigenschaft und store_name und store_address als Tabellendaten gespeichert. Verzeichnisse und Dateien Führen Sie folgende Befehle aus, um die notwendigen Verzeichnisse und die notwendige Verzeichnisstruktur zum Speichern von Skripten, Vorlagen und generierten Seiten zu erstellen: md d:\sql_web md d:\sql_web\scripts md d:\sql_web\pubs md d:\sql_web\pubs\stores Das Verzeichnis "Scripts" Erstellen Sie als nächstes ein virtuelles Verzeichnis, das auf das Verzeichnis D:\Sql_web\Scripts zeigt. Nennen Sie dieses virtuelle Verzeichnis /sqlscripts, und gewähren Sie ihm nur Ausführungsberechtigungen. Kopieren Sie folgende Dateien in das Verzeichnis D:\Sql_web\Scripts. Genstores.idc Eine Skriptdatei zum Generieren von Webseiten für alle Tabellenzeilen der StoresTabelle. Genstores.htx Eine Vorlagendatei für Genstores.idc. Stores.tpl Eine Vorlagendatei mit Formatierungsinformationen zu den generierten Seiten in der Stores-Tabelle. Das Verzeichnis der generierten Seiten Die Seiten, die SQL Server automatisch für die Stores-Tabelle generiert, werden im Verzeichnis D:\Sql_web\Pubs\Stores abgelegt. Erstellen Sie ein virtuelles Verzeichnis mit dem Namen /pubs, und verweisen Sie es auf D:\Sql_web\Pubs. Gewähren Sie /pubs Leseberechtigungen. Mit dieser Konfiguration kann Index Server alle Seiten in D:\Sql_web\Pubs und den Unterverzeichnissen indizieren. Der Primärschlüssel ist im Dateinamen jeder generierten Seite enthalten. Damit wird sichergestellt, dass jeder Dateiname eindeutig und jeder Datensatz mit einer Webseite verknüpft ist. Wenn die stor_id z. B. 3456 lautet, hat die generierte Webseite folgenden Namen: D:\Sql_web\Pubs\Stores\3456.htm. Die gespeicherte Prozedur "wp_stores_update" Die gespeicherte Prozedur wp_stores_update generiert eine Webseite für eine Zeile in der Stores-Tabelle mit Hilfe der gespeicherten Systemprozedur sp_makewebtask. Die gespeicherte Prozedur wp_stores_update gibt eine Abfrage anhand von stor_id, dem Primärschlüssel der Stores-Tabelle, aus. Aus diesem Grund wird bei Übereinstimmung mit einer spezifischen Store-ID nur eine Seite generiert. USE PUBS GO if exists (select * from sysobjects where id = object_id('dbo.wp_stores_update') and sysstat & 0xf = 4) drop procedure dbo.wp_stores_update GO CREATE PROCEDURE dbo.wp_stores_update @storid char(4), -- Primary Key, id of the store @filepath varchar(100), -- Directory where to create the Web page @templatefile varchar(100) = NULL -- Optional template file to use AS --- This procedure creates a Web page for a row with the specified stor_id -- which is a key in the stores table. -- --- Forming the strings to give to the "EXEC" command is confusing when -- we have run time variables in the string. Splitting it up into variables -- will make it a little more readable. -DECLARE @cmd_text1 varchar(255) DECLARE @cmd_text2 varchar(255) DECLARE @file_name varchar(255) --- Compose the file name using the primary key "storid". -- For example, if the storid is 3456 and @filepath is d:\sql_web\pubs\stores -- the generated Web page will be d:\sql_web\pubs\stores\3456.htm -SELECT @file_name=@filepath+'\'+@storid+'.htm' --- Compose the sp_makewebtask command and parameters. -- Note that stor_id is being retrieved twice because we want to -- Use one instance for a meta tag and another for a table value. -SELECT @cmd_text1='sp_makewebtask @outputfile='''+@file_name+''',\ @query=''SELECT stor_id, stor_id, stor_name,stor_address FROM stores \ WHERE stores.stor_id='''''+@storid+''''''+'''' --- If a template file is specified, use it -IF @templatefile <> NULL BEGIN SELECT @cmd_text2=',@templatefile='''+@templatefile+'''' END --- For debugging purposes ---PRINT @file_name --PRINT @cmd_text1 --PRINT @cmd_text2 EXECUTE( @cmd_text1+@cmd_text2 ) GO web_stores_update_trigger Die Entwicklung von Triggern ist optional, es sei denn, Sie möchten Webseiten automatisch generieren, wenn sich die Tabelle ändert. In diesem Fall ist ein Trigger notwendig. Dieser Trigger verwendet die gespeicherte Prozedur wp_stores_update, um eine Webseite für eine geänderte Zeile zu generieren. USE pubs go if exists (select * from sysobjects where id = object_id('dbo.web_stores_update_trigger') and sysstat & 0xf = 8) drop trigger dbo.web_stores_update_trigger go --- This trigger will generate a Web page for the records -- that match the given stor_id. Since stor_id is a primary -- key, only one page will be generated. -CREATE TRIGGER web_stores_update_trigger ON dbo.stores FOR INSERT,UPDATE AS DECLARE @newstorid char(4) DECLARE @cmd_text varchar(255) --- Get the stor_id of the row that just changed into the -- @newstorid variable. -SELECT @newstorid = i.stor_id FROM inserted i select @cmd_text='wp_stores_update''' + @newstorid + ''',\ @filepath=''D:\sql_web\pubs\stores'',@templatefile=''D:\sql_web\scripts\stores.tpl''' EXEC(@cmd_text) GO web_stores_delete_trigger Der web_stores_delete_trigger löscht eine Webseite, wenn ein Datensatz aus der Stores-Tabelle entfernt wird. USE pubs GO if exists (select * from sysobjects where id = object_id('dbo.web_stores_delete_trigger') and sysstat & 0xf = 8) drop trigger dbo.web_stores_delete_trigger GO --- This trigger will delete the Web page for the record that -- got deleted. Since stor_id is a primary key and the page -- was originally generated using the stor_id in the file name -- only one page will get deleted. -CREATE TRIGGER web_stores_delete_trigger ON dbo.stores FOR DELETE AS DECLARE @cmd_text varchar(255) DECLARE @deletedstorid char(4) --- Determine the row which got deleted and store its -- value in @deletedstorid. -SELECT @deletedstorid = d.stor_id FROM deleted d -- ------- Generate the Web page to be deleted using the storid. For example, if the storid is 3456 and @filepath is d:\sql_web\pubs\stores the generated Web page will be d:\sql_web\pubs\stores\3456.htm Run an NT command to delete the HTML file corresponding to that record. select @cmd_text='master..xp_cmdshell ''del d:\sql_web\pubs\stores\' + @deletedstorid + '.htm'',no_output' EXEC(@cmd_text) GO Die Vorlagendatei Stores.tpl für generierte Seiten Die Vorlagendatei Stores.tpl dient zum Formatieren der generierten Seiten in der StoresTabelle. Die Vorlage hält sich an die in der SQL Server-Dokumentation beschriebenen Syntax für die Verwendung der gespeicherten Systemprozedur sp_makewebtask. Beachten Sie, dass die erste Spalte, stor_id, als Metatag mit dem Namen stor_id gespeichert wurde. Index Server ist zum Durchsuchen von Metatags in der Lage. Die gespeicherte Prozedur sp_makewebtask ersetzt die <%insert_data_here%>-Tags mit den Spalten für jede Zeile. Die Reihenfolge ist mit der Reihenfolge in der SELECT-Anweisung der gespeicherten Prozedur wp_stores_update identisch. Der folgende HTML-Code stammt aus der Datei Stores.tpl. <HTML> <HEAD> <TITLE>SQL Server Pubs Database,Stores Table</TITLE> <BODY> <H1>Stores Table Row</H1> <HR> <%begindetail%> <META NAME="stor_id" CONTENT=" <%insert_data_here%>"> <TABLE> <TR> <TD> <B>StoreId</B> </TD> <TD> <%insert_data_here%> </TD> </TR> <TR> <TD> <B>StoreName</B> </TD> <TD> <%insert_data_here%> </TD> </TR> <TR> <TD> <B>StoreAddress</B> </TD> <TD> <%insert_data_here%> </TD> </TR> </TABLE> <%enddetail%> </BODY> </HTML> Die Skriptdatei "Genstores.idc" Die Skriptdatei Genstores.idc führt einen SQL-Befehl aus, der Webseiten für alle Datensätze in der Stores-Tabelle generiert. Wenn Sie das Datenbankbeispiel noch nicht wie in der IIS-Dokumentation beschrieben eingerichtet haben, sollten Sie einen ODBC-Eintrag wie auf der Beispielseite der IISDatenbank einrichten. Bei diesen Beispielen wird davon ausgegangen, dass die Datei Genstores.idc sich im physischen Verzeichnis D:\Sql_web\Scripts befindet, dem das virtuelle Verzeichnis /sqlscripts zugeordnet ist. Folgender Text ist in der Datei Genstores.idc enthalten. Wenn Sie das Kennwort für das Konto sa geändert haben oder ein anderes Konto verwenden möchten, müssen Sie das folgende Skript entsprechend ändern. Datasource: web sql Username: sa Template: genstores.htx SQLStatement: +USE pubs +DECLARE stores_cursor CURSOR + FOR + SELECT stor_id FROM STORES +OPEN stores_cursor +DECLARE @storid char(4) +FETCH NEXT FROM stores_cursor INTO @storid +WHILE (@@fetch_status <> -1) +BEGIN + /* + A @@fetch_status of -2 means that the row has been deleted. + No need to test for this as the result of this loop is to + drop all user-defined tables. + */ + EXEC ('wp_stores_update ' + '''' + @storid + '''' + + ',@filepath=''D:\sql_web\pubs\stores'',@templatefile= ''D:\sql_web\scripts\stores.tpl''') + FETCH NEXT FROM stores_cursor INTO @storid +END +DEALLOCATE stores_cursor Die Vorlagendatei "Genstores.htx" Die Vorlage Genstores.htx ist der Datei Genstores.idc zugeordnet. Sie müssen diese beiden Dateien im Verzeichnis D:\Sql_web\Scripts ablegen. Genstores.htx enthält folgenden Code: <HTML> <HEAD><TITLE>SQL Server Web Page Generation Example</TITLE></HEAD> <BODY BACKGROUND="/samples/images/backgrnd.gif"> <BODY BGCOLOR="FFFFFF"> <TABLE> <tr> <TD></TD> <TD> <H2> Success!! </H2> </TD> </TR> </TABLE> </BODY> </HTML> Testlauf Nachdem Sie alle Schritte des Stores-Beispiels ausgeführt haben, können Sie die gespeicherte Prozedur, sowie die Vorlagen und Trigger testen, indem Sie folgende SQLAbfragen im Programm ISQL/w ausführen. wp_stores_update Wenn Sie das gleiche physische Verzeichnislayout wie in diesem Dokument beschrieben verwenden, können Sie feststellen, ob die Prozedur wp_stores_update ordnungsgemäß erstellt wurde. Anmerkung Voraussetzung hierfür ist, dass '6380' eine gültige stor_id darstellt. Ist dies nicht der Fall ersetzen Sie '6380' durch eine gültige stor_id. Geben Sie folgende Abfrage ein: EXEC ('wp_stores_update @stor_id=''6380'',\ @filepath=''D:\Sql_web\pubs\stores'',\ @templatefile=''D:\sql_web\scripts\stores.tpl''') Wichtiger Hinweis Im vorstehenden Beispiel wurden nur einfache Anführungszeichen verwendet. Die mit diesem Beispiel generierte HTML-Seite wird im Verzeichnis D:\Sql_web\Pubs\Stores\6380.htm gespeichert und sieht wie folgt aus: <HTML> <HEAD> <TITLE>SQL Server Pubs Database,Stores Table</TITLE> <BODY> <H1>Stores Table Row</H1> <HR> <META NAME="stor_id" CONTENT="6380"> <TABLE> <TR> <TD> <B>StoreId</B> </TD> <TD> 6380 </TD> </TR> <TR> <TD> <B>StoreName</B> </TD> <TD> Eric the Read Books </TD> </TR> <TR> <TD> <B>StoreAddress</B> </TD> <TD> 788 Catamaugus Ave. </TD> </TR> </TABLE> </BODY> </HTML> web_stores_update_trigger Vorausgesetzt, dass es keinen Eintrag mit der stor_id '1234' gibt, können Sie den INSERT-Trigger mit folgender Abfrage testen: INSERT INTO Stores (stor_id, store_name, store_address,city,state,zip) VALUES('1234', 'Discount Book Stores', '1234 First Avenue', 'Seattle', 'WA','98000') web_stores_delete_trigger Nachdem die Zeile eingefügt wurde, können Sie den DELETE-Trigger mit folgender Abfrage testen: DELETE FROM Stores Where stor_id='1234' Generierte Webseiten Wenn Sie die vorstehenden Schritte erfolgreich ausgeführt haben, können Sie testen, ob die Seiten ordnungsgemäß generiert werden. Führen Sie das Skript Genstores.idc in einem Browser aus: http://servername/sqlscripts/Genstores.idc Beispiel 2: "Pub_Info"-Tabelle In "Beispiel 1: Stores-Tabelle" enthielten alle drei abgerufenen Spalten (stor_id, store_name, store_address) weniger als 255 Zeichen, damit sie in der generierten Webseite inline abgerufen werden konnten. Wenn aber eine Spalte vom Variablentyp SQL TEXT vorhanden ist, beschränkt die gespeicherte Prozedur sp_makewebtask die Ausgabe auf 255 Zeichen. Sie können diese Einschränkung mit dem @blobfmt-Parameter umgehen. Ausführliche Informationen finden Sie in der SQL Server-Dokumentation. Im Prinzip ruft @blobfmt Spalten mit TEXT-Daten ab und legt sie ohne Einschränkung in einer separaten Datei ab. Dieser Parameter erstellt ebenfalls eine Verknüpfung von der Hauptseite zu der separaten Datei, in der die Daten gespeichert sind (der untergeordneten Seite). Index Server kann die Haupt- und untergeordnete Seite getrennt indizieren. Es ist nicht einfach, die Hauptseite ausgehend von der untergeordneten Seite zu finden. Wenn Index Server einen Treffer auf einer untergeordneten Seite findet, wird deshalb nur diese, nicht aber die Hauptseite zurückgegeben. Im nächsten Beispiel wird die Pub_info-Tabelle in der pubs-Beispieldatenbank verwendet. Ausführliche Erklärungen zu gespeicherten Prozeduren, Triggern, Skripten und Vorlagen finden Sie in den entsprechenden Abschnitten in "Beispiel 1: Stores-Tabelle". Schema für die Pub_Info- und Publishers-Tabelle Die folgende Tabelle zeigt das Schema der Pub_Info-Tabelle: Spaltenname Datentyp pub_id char(4) logo pr_info IMAGE TEXT Schlüssel/Index Primärschlüssel und auch Fremdschlüssel Da pub_id den Primärschlüssel darstellt, generieren Sie mit pub_id einen eindeutigen Dateinamen für jeden Datensatz in der Tabelle. In diesem Beispiel rufen Sie die TEXT-Daten von pr_info in eine separate Datei ab und verknüpfen diese mit der Hauptseite. Sie werden ebenfalls eine Verknüpfung mit der Publishers-Tabelle in der gespeicherten Prozedur durchführen, um eine leichte Abwandlung zu veranschaulichen. Die folgende Tabelle zeigt das Schema der Publishers-Tabelle: Spaltenname pub_id pub_name city state country Datentyp char(4) varchar(40) varchar(20) char(2) varchar(30) Schlüssel/Index Primärschlüssel Die pub_id ist der Primärschlüssel der Publishers-Tabelle. Pub_Info.pub_id ist ein mit Publishers.pub_id verknüpfter Fremdschlüssel. Verzeichnisse und Dateien Führen Sie folgende Befehle aus, um Verzeichnisse zum Speichern von Skripts, Vorlagen und generierten Seiten zu erstellen: md d:\sql_web md d:\sql_web\scripts md d:\sql_web\pubs md d:\sql_web\pubs\pub_info Das Verzeichnis "Scripts" Legen Sie als Nächstes folgende Dateien im Verzeichnis D:\Sql_web\Scripts ab. In "Beispiel 1: Stores-Tabelle" haben Sie aus diesem Verzeichnis ein virtuelles Verzeichnis (/sqlscripts) erstellt und ihm Ausführungsberechtigungen gewährt. Genpub_info.idc Genpub_info.htx Pub_info.tpl Pr_info.tpl Das Verzeichnis der generierten Seiten Die aus der Pubs_Info-Tabelle generierten Webseiten werden im Verzeichnis D:\Sql_web\Pubs\Pub_info gespeichert. Das virtuelle Verzeichnis /pubs verweist auf das Verzeichnis D:\Sql_web\Pubs und muss über Leseberechtigungen verfügen. Bei dieser Konfiguration kann Index Server die Seiten Indizieren, und IIS kann die generierten Seiten oder Ergebnisse anzeigen. Die gespeicherte Prozedur "wp_pub_info_update" Geben Sie folgende SQL-Abfragen im Programm ISQL/w ein. USE pubs GO if exists (select * from sysobjects where id = object_id('dbo.wp_pub_info_update') and sysstat & 0xf = 4) drop procedure dbo.wp_pub_info_update GO CREATE PROCEDURE wp_pub_info_update @pubid char(4), -- Publishers id @filepath varchar(100), -- Directory in which to generate pages @pr_infotmpl varchar(100), -- Template file for pr_info (text) field @maintmpl varchar(100) = NULL -- Template file for main page AS --------- The stored procedure illustrates the use of @blobfmt parameter to retrieve TEXT data to a 'sub-file'. For example, if the pub_id is '0736' and @filepath is d:\sql_web\pubs\pub_info, the main page will have the name d:\sql_web\pubs\pub_info\0736.htm and the linked file will have the name d:\sql_web\pubs\pub_info\pr_info07361.htm. The "1" is appended by sp_makewebtask. --- It is easier to construct an execution statement using variables. -DECLARE DECLARE DECLARE DECLARE DECLARE @cmd_text1 @cmd_text2 @cmd_text3 @cmd_text4 @cmd_text5 varchar(255) varchar(255) varchar(255) varchar(255) varchar(255) --- mainfile will contain the name of the main file. -DECLARE @mainfile varchar(255) --- pr_infofile will contain the name of the file that will have the -- pr_info text field. -DECLARE @pr_infofile varchar(255) --- @filepath and @pr_infotmpl cannot be NULL -IF (@filepath = NULL) BEGIN RAISERROR(16853,11,1) RETURN (9) END IF (@pr_infotmpl = NULL) BEGIN RAISERROR(16853,11,1) RETURN (9) END --- If @filepath is d:\sql_web\pubs\pub_info, the main page will have -- the name d:\sql_web\pubs\pub_info\0736.htm and the linked file will have -- the name d:\sql_web\pubs\pub_info\pr_info07361.htm. The "1" is appended -- by sp_makewebtask. -SELECT @mainfile=@filepath+'\'+@pubid+'.htm' SELECT @pr_infofile=@filepath+'\pr_info'+@pubid+'.htm' --- For Debugging purposes ---PRINT @pubid --PRINT @filepath --PRINT @maintmpl --PRINT @pr_infofile --- In this example, we are retrieving pub_id in two columns so we -- can use the first one for a META property. -SELECT @cmd_text1='sp_makewebtask @outputfile='''+@mainfile+''',\ @query=''SELECT pub_info.pub_id, pub_info.pub_id, pr_info, pub_name,city,state,country \ FROM pub_info, publishers WHERE pub_info.pub_id=''''' SELECT @cmd_text2=@pubid+''''' AND pub_info.pub_id=publishers.pub_id' SELECT @cmd_text3=''',@blobfmt=''%3% FILE='+@pr_infofile SELECT @cmd_text4=' TPLT='+@pr_infotmpl+'''' IF @maintmpl <> NULL BEGIN SELECT @cmd_text5=',@templatefile='''+@maintmpl+'''' END --- For Debugging purposes ---PRINT @mainfile --PRINT @cmd_text1 --PRINT @cmd_text2 --PRINT @cmd_text3 --PRINT @cmd_text4 --PRINT @cmd_text5 EXECUTE( @cmd_text1+@cmd_text2+@cmd_text3+@cmd_text4+@cmd_text5 ) GO web_pub_info_update_trigger Beim folgenden Code handelt es sich um den UPDATE-Trigger für die Pub_Info-Tabelle. use pubs if exists (select * from sysobjects where id = object_id('dbo.web_pub_info_update_trigger') and sysstat & 0xf = 8) drop trigger dbo.web_pub_info_update_trigger GO --- This trigger will generate a Web page for the records -- that match the given pub_id. Since pub_id is a primary -- key, only one page will be generated. -CREATE TRIGGER web_pub_info_update_trigger ON dbo.pub_info FOR INSERT,UPDATE AS DECLARE @pubid char(4) DECLARE @cmd_text1 varchar(255) DECLARE @cmd_text2 varchar(255) DECLARE @cmd_text3 varchar(255) DECLARE @cmd_text4 varchar(255) --- Get the stor_id of the row that just changed into the -- @newpubid variable. -SELECT @pubid = i.pub_id FROM inserted i select select select select @cmd_text1='wp_pub_info_update @pubid=''' + @pubid @cmd_text2=''',@filepath=''D:\sql_web\pubs\pub_info'',' @cmd_text3='@pr_infotmpl=''d:\sql_web\scripts\pr_info.tpl'',' @cmd_text4='@maintmpl=''D:\sql_web\scripts\pub_info.tpl''' EXEC(@cmd_text1+@cmd_text2+@cmd_text3+@cmd_text4) GO web_pub_info_delete_trigger Beim folgenden Code handelt es sich um den DELETE-Trigger für die Pub_Info-Tabelle. USE pubs GO if exists (select * from sysobjects where id = object_id('dbo.web_pub_info_delete_trigger') and sysstat & 0xf = 8) drop trigger dbo.web_pub_info_delete_trigger GO --- This trigger will delete the Web page for the record that -- got deleted. Since pub_id is a primary key and the page -- was originally generated using the page_id in the file name -- only one page will get deleted. -CREATE TRIGGER web_pub_info_delete_trigger ON dbo.pub_info FOR DELETE AS DECLARE @pubid char(4) DECLARE @mainfile varchar(255) DECLARE @pr_infofile varchar(255) DECLARE @cmd_text1 varchar(255) DECLARE @cmd_text2 varchar(255) --- Determine the row which got deleted and store its -- value in @deletedstorid. -SELECT @pubid = d.pub_id FROM deleted d --- Generate the Web page to be deleted using the pubid. -SELECT @mainfile='d:\sql_web\pubs\pub_info\'+@pubid+'.htm' --- Note that it is '1.htm' after the @pubid because that is how SQL -- Server generates the name of the sub-link. For example, if the id is 9912, -- the name of the file generated is d:\sql_web\pubs\pub_info\pr_info99121.htm -SELECT @pr_infofile='d:\sql_web\pubs\pub_info\pr_info'+@pubid+'1.htm' SELECT @cmd_text1='master..xp_cmdshell ''del ' SELECT @cmd_text2=''',no_output' --PRINT --PRINT --PRINT --PRINT @mainfile @pr_infofile @cmd_text1 @cmd_text2 EXEC( @cmd_text1+@mainfile+@cmd_text2) EXEC( @cmd_text1+@pr_infofile+@cmd_text2) GO Die Skriptdatei "Genpub_info.idc" Die Skriptdatei Genpub_info.idc kann die Webseiten in einem Batch erstellen und enthält folgenden Code: Datasource: web sql Username: sa Template: genpub_info.htx SQLStatement: +USE pubs +DECLARE pub_info_cursor CURSOR + FOR + SELECT pub_id FROM pub_info +OPEN pub_info_cursor +DECLARE @pubid char(4) +FETCH NEXT FROM pub_info_cursor INTO @pubid +WHILE (@@fetch_status <> -1) +BEGIN + /* + A @@fetch_status of -2 means that the row has been deleted. + No need to test for this as the result of this loop is to + drop all user-defined tables. + */ +EXEC ('wp_pub_info_update @pubid=' + '''' + @pubid + '''' + +',@filepath=''D:\sql_web\pubs\pub_info'','+ +'@pr_infotmpl=''d:\sql_web\scripts\pr_info.tpl'','+ +'@maintmpl=''D:\sql_web\scripts\pub_info.tpl''') +FETCH NEXT FROM pub_info_cursor INTO @pubid +END +DEALLOCATE pub_info_cursor Die Vorlagendatei "Genpub_info.htx" Genpub_info.htx ist mit der Datei Genstores.htx identisch und enthält folgenden Code: <HTML> <HEAD><TITLE>SQL Server Web Page Generation Example</TITLE></HEAD> <BODY BACKGROUND="/samples/images/backgrnd.gif"> <BODY BGCOLOR="FFFFFF"> <TABLE> <tr> <TD></TD> <TD> <H2> Success!! </H2> </TD> </TR> </TABLE> </BODY> </HTML> Die Vorlagendatei "Pr_info.tpl" Die Vorlagendatei Pr_info.tpl wird durch den @blobfmt-Parameter festgelegt und enthält Formatierungsinformationen zu den TEXT-Daten pr_info, die in einer separaten Datei gesammelt wurden. Der folgende Code stammt aus der Datei Pr_info.tpl. <HTML> <HEAD> <TITLE>Pr_Info Table, Pr_Info Text Field</TITLE> <BODY> <H2>Large amount of text from Pr_Info Text Field</H2> <HR> <%insert_data_here%> </BODY> </HTML> Die Vorlagendatei "Pub_info.tpl" Die Vorlagendatei Pub_info.tpl legt das Format der Hauptdatei fest und enthält folgenden Code: <HTML> <HEAD> <TITLE>Pubs Database, Pub_Info Table</TITLE> <BODY> <%begindetail%> <META NAME="pub_id" CONTENT="<%insert_data_here%>"> <H1>Publisher Info For PublisherId <%insert_data_here%></H1> <HR> <TABLE> <TR> <TD> <B>Publisher Name:</B> </TD> <TD><%insert_data_here%> </TD> </TR> <TR> <TD> <B>City:</B> </TD> <TD> <%insert_data_here%> </TD> </TR> <TR> <TD> <B>State:</B> </TD> <TD> <%insert_data_here%> </TD> </TR> <TR> <TD> <B>Country:</B> </TD> <TD> <%insert_data_here%> </TD> </TR> </TABLE> <%enddetail%> </BODY> </HTML> Testlauf Nachdem Sie alle Schritte des Pub_Info-Beispiels ausgeführt haben, können Sie die gespeicherte Prozedur, sowie die Vorlagen und Trigger testen, indem Sie folgende SQL-Abfragen im Programm ISQL/w ausführen. wp_pub_info_update Wenn '0736' eine gültige pub_id ist, können Sie die Prozedur wp_pub_info_update testen, indem Sie folgende Abfrage eingeben. EXEC('wp_pub_info_update @pubId=''0736'',\ @filepath=''d:\sql_web\pubs\pub_info'',\ @pr_infotmpl=''d:\sql_web\scripts\pr_info.tpl'',\ @maintmpl=''d:\sql_web\scripts\pub_info.tpl''') Die in diesem Beispiel generierten HTML-Seiten (0736.htm und 07361.htm) werden im Verzeichnis D:\Sql_web\Pubs\Pub_info gespeichert und sehen wie folgt aus: 0736.htm <HTML> <HEAD> <TITLE>Pubs Database, Pub_Info Table</TITLE> <BODY> <META NAME="pub_id" CONTENT="0736"> <H1>Publisher Info For PublisherId 0736</H1> <HR> <TABLE> <TR> <TD> <B>Publisher Name:</B> </TD> <TD><A HREF = "file:///d:\sql_web\pubs\pub_info\pr_info07361.htm">New Moon Books</A> </TD> </TR> <TR> <TD> <B>City:</B> </TD> <TD> Boston </TD> </TR> <TR> <TD> <B>State:</B> </TD> <TD> MA </TD> </TR> <TR> <TD> <B>Country:</B> </TD> <TD> USA </TD> </TR> </TABLE> </BODY> </HTML> 07361.htm <HTML> <HEAD> <TITLE>Pr_Info Table, Pr_Info Text Field</TITLE> <BODY> <H2>Large amount of text from Pr_Info Text Field</H2> <HR> Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. Dies sind Beispieltextdaten für New Moon Books, Verlag 0736 in der pubs-Datenbank. New Moon Books ist in Boston, Massachusetts, ansässig. </BODY> </HTML> web_pub_info_update_trigger Mit diesem Test wird der INSERT-Trigger überprüft. Da pub_info.pub_id ein Fremdschlüssel in der Publishers-Tabelle ist, müssen Sie zuerst eine Zeile in der Publishers-Tabelle einfügen. insert into publishers (pub_id, pub_name,city,state,country) values('9914','Discount Publishers', 'Seattle', 'Wa', 'USA') go insert into pub_info (pub_id, pr_info) values('9914', 'This is the pr_info for Discount Publishers in Seattle, WA, USA') go web_pub_info_delete_trigger Mit diesem Test wird der DELETE-Trigger überprüft. delete from pub_info where pub_id='9914' go delete from publishers where pub_id='9914' go