(przepraszam z góry za okropnego wyjaśnienia, ale jeśli uruchomić zapytań Poniżej powinien zobaczyć, co mam na myśli!)Dlaczego SQL ocenia wyciągi w prawdziwej sekcji konstruktu if, nawet jeśli `if exists` zwraca false?
Dlaczego MSSQL oceny sprawozdań w sekcji true
wystąpienia if exists
konstruktem, nawet jeśli if exists
powraca false, powodując błędy?
Na przykład w dwóch poniższych zapytaniach pierwsza sprawdza, czy tabela istnieje (co robi), a także sprawdza, czy ta tabela zawiera określone kolumny. Z jakiegoś powodu uruchomienie tej kwerendy powoduje następujące błędy, ponieważ tabela istnieje, ale kolumny nie.
Msg 207, Level 16, State 1, Line 21
Invalid column name 'colB'.
Msg 207, Level 16, State 1, Line 21
Invalid column name 'colC'.
Msg 207, Level 16, State 1, Line 21
Invalid column name 'colA'.
Zachowanie Spodziewałem tutaj było dla SQL po prostu przenieść na falsepart
konstruktu, bez rzucania błędów. (Podobnie jak w przypadku następnego zapytania).
Jednak drugi skrypt (który jest identyczny, nazwy tablic słupkowych) działa poprawnie. Dzieje się tak dlatego, że tabela, której szuka zapytanie, nie istnieje.
--Scripts to setup the example.
CREATE DATABASE TEST
GO
USE TEST
GO
CREATE TABLE t1 (colD VARCHAR(255)) --Create a table with the correct name, but incorrect column names.
GO
--This query fails, because t1 exists, even though the columns in t1 don't.
IF EXISTS (select * from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1' AND COLUMN_NAME IN ('colA','colB','colC'))
BEGIN
SELECT colA FROM t1 WHERE colB = 0 AND colC = 1
END
ELSE BEGIN
SELECT 'FALSE'
END
GO
--This query executes ok, because t2 does not exist.
IF EXISTS (select * from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't2' AND COLUMN_NAME IN ('colA','colB','colC'))
BEGIN
SELECT colA FROM t2 WHERE colB = 0 AND colC = 1
END
ELSE BEGIN
SELECT 'FALSE'
END
Czy ktoś może mi wyjaśnić, dlaczego błędy pierwszego zapytania, gdy drugie zapytanie działa poprawnie?
Do tej pory udało mi się jedynie do sprawdzenia tego w Microsoft SQL Server 2012.
Nie udało się * skompilować * partii, nawet nie udało się uzyskać * uruchomienia * kodu. Rozważmy, w języku C#, czy masz ładunek wywołań odbicia, aby sprawdzić, czy dana klasa zawiera konkretną metodę. Nie możesz po prostu mieć tych kontroli w 'if', a następnie w treści' if' mieć linię, która * wywołuje * tę metodę na instancji klasy - z tego samego powodu - nie powiedzie się * skompilować*. –
@Damien_The_Unbeliever, Rozumiem, co masz na myśli, ale jeśli nie uda się skompilować partii, ponieważ * niektóre * obiektów nie istnieją, dlaczego drugie zapytanie uruchamia się, gdy * none * obiektu istnieje? – KidCode
Sytuacja z tabelą jest nieco dziwniejsza, ale dzieje się tak z powodu [rozpoznawania nazw odroczonych] (https://technet.microsoft.com/en-us/library/ms190686 (v = sql.105) .aspx) (jedno miejsce gdzie SQL celowo odkłada kompilację, aż do wyciągnięcia tego oświadczenia) –