6 Stimmen

Wie funktioniert SET NOEXEC ON?

Ich habe folgenden Code:

-- Start des Codes
set noexec off

declare @requiredVersion int
declare @currentVersion int

set @requiredVersion = 5
set @currentVersion = 4

if (@currentVersion < @requiredVersion)
begin
    print 'Bitte aktualisieren Sie Ihre DB auf Version 5, bevor Sie dieses Skript ausführen.'
    set noexec on
end

go
-- print 'Dummy'
insert into tblFooBar(name) values ('AAA')
go

set noexec off
-- Ende des Codes

Bitte beachten Sie, dass die Tabelle "tblfoobar" in der Datenbank nicht existiert. Wenn ich diesen Code ausführe, erscheint die Meldung:

Bitte aktualisieren Sie Ihre DB auf Version 5, bevor Sie dieses Skript ausführen.
Msg 208, Level 16, State 1, Zeile 1
Ungültiger Objektname 'tblFooBar'.

Ich hatte erwartet, dass das Setzen von noexec auf ON den Teil "Msg 208" der Meldung nicht anzeigen würde.

Wiederum kompiliert "set noexec on" den Code, führt ihn nicht aus. Versuchen, etwas in eine nicht vorhandene Tabelle einzufügen, ist ein Compile-Zeitfehler - ich vermute. Wenn das der Fall ist, sollte der Fehler bezüglich des "fehlenden Objekts" auftreten.

Jetzt will ich Ihnen das seltsame Verhalten erklären, das ich beobachtet habe. Wenn ich den Kommentar aus der Zeile "-- Print 'dummy'" entferne

-- Start des Codes
set noexec off

declare @requiredVersion int
declare @currentVersion int

set @requiredVersion = 5
set @currentVersion = 4

if (@currentVersion < @requiredVersion)
begin
    print 'Bitte aktualisieren Sie Ihre DB auf Version 5, bevor Sie dieses Skript ausführen.'
    set noexec on
end
go
print 'Dummy'
insert into tblFooBar(name) values ('AAA')
go

und den Code ausführe, erhalte ich nur folgende Meldung.

Bitte aktualisieren Sie Ihre DB auf Version 5, bevor Sie dieses Skript ausführen.

Diesmal gibt es keine Meldung über eine fehlende Tabelle.

Kann mir jemand dieses Verhalten bitte erklären? Danke.

0 Stimmen

Nur um sicherzustellen, dass wir auf derselben Seite sind: Ist das für den SQL Server? Welche Version?

0 Stimmen

Entschuldigung, ich hätte das erwähnen sollen. Ich habe diesen Code mit MS SQL 2000 ausprobiert.

0 Stimmen

Ich sehe das gleiche Verhalten in SQL 2005.

4voto

MikeW Punkte 5552

Ich hätte nicht erwartet, dass es gültig ist, "set noexec" innerhalb einer Bedingung wie von Ihnen angegeben zu verwenden, aber tatsächlich scheint es gültig zu sein.

Das Verhalten scheint mit der Tatsache zusammenzuhängen, dass es sich um ein DDL-Statement handelt. Wenn Sie Ihr INSERT durch ein PRINT-Statement oder eine einfache SELECT-Abfrage ersetzen, funktioniert das Skript wie erwartet.

Übrigens, wenn ich so etwas tun möchte, verwende ich folgenden Ansatz:

    create proc tmproc\_foobar as
       CREATE TABLE tblFooBar( name nvarchar(20) )
    go

    if exists ( select 1 from sysobjects where type = 'U' and name = 'tblFooBar' )
         exec tmproc\_foobar
    go

    drop proc tmproc\_foobar
    go

SQL Server erlaubt es Ihnen, eine gespeicherte Prozedur mit einem Objekt zu erstellen, das nicht existiert, so dass Sie die Prozedur erstellen, sie bedingt ausführen und dann löschen können. Auf diese Weise habe ich ein langes Upgrade-Skript, das fehlende Objekte in meiner Datenbank bedingt hinzufügt.

Sie könnten dies vielleicht anpassen. Dann benötigen Sie den noexec im ersten Schritt gar nicht, weil Sie das gesamte Problem ungültiger Objekte vermeiden.

0 Stimmen

Wenn ich INSERT durch SELECT ersetze und die PRINT-Anweisung kommentiere, erhalte ich die erste Fehlermeldung (fehlendes Objekt). Wenn ich die PRINT-Anweisung beibehalte, erhalte ich die zweite Fehlermeldung (nichts über fehlendes Objekt). Das Skript funktioniert nicht wie erwartet (von mir), wenn ich das INSERT durch ein SELECT aus tblfoobar ersetze.

2voto

Ich habe den obigen Code überprüft und er funktioniert einwandfrei. Es gibt keine Fehlermeldung für fehlende Objekte.

set noexec off

declare @requiredVersion int
declare @currentVersion int

set @requiredVersion = 5
set @currentVersion = 4

if (@currentVersion < @requiredVersion)
begin
    print 'Bitte aktualisieren Sie Ihre DB auf Version 5, bevor Sie dieses Skript ausführen.'
    set noexec on--> hier setzen wir NOEXEC ein
end

go
-- print 'Dummy'
insert into tblFooBar(name) values ('AAA')
go

set noexec off
-- Ende des Codes

Da NOEXEC aktiviert ist, wird der folgende Code kompiliert und nicht ausgeführt, daher wird keine Fehlermeldung angezeigt.

0 Stimmen

Es scheint jetzt gut zu funktionieren! Vor 5 Jahren hat es nicht funktioniert, und ich glaube, einige der Kommentare anderer Benutzer haben es bestätigt.

0voto

Charming Green Punkte 13

Ich stieß auf das gleiche Problem und fand einen besseren Weg, um das Problem zu lösen. Einfach den kompilierten Fehlerinhalt in eine EXEC-Anweisung wie diese einfügen:

EXEC('
 -- Hier den kompilierten Fehler einfügen
')

Dadurch sparen Sie auch eine GO-Anweisung und ersetzen einfach das einfache "'" durch doppelte "''", um den Code hier einzufügen. Diese EXEC-Anweisung kann den kompilierten Fehler vermeiden und die Wünsche erreichen, die Sie ursprünglich hatten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X