Podczas tworzenia procedury składowanej w SQL Server możesz odwoływać się do tabel, które nie istnieją. Ale jeśli tabela istnieje, to każda kolumna, do której odwołujesz się w procedurze, musi istnieć w tej tabeli ( rozpoznawanie nazw odroczonych ).
Czy można polecić SQL Serverowi odroczenie rozpoznawania nazw wszystkich tabel, do których istnieją odniesienia w procedurze, niezależnie od tego, czy istnieją? Chcę zachować ogólne sprawdzanie składni, więc nawet gdyby było to możliwe, włamanie definicji procedury składowanej do tabeli systemowej nie jest opcją.
Spodziewam się, że moje zapytanie może wydawać się nieco dziwne , więc oto kilka podstaw: automatycznie generuję definicje tabel i procedury składowane z aplikacji napisanej w C # i bardzo trudno jest mi zmienić kod, aby zamówić zmiany zgodnie z potrzebami SQL im. Mój kod „gwarantuje”, że schemat jest spójny w ramach transakcji, ale obecnie nie mogę zagwarantować, że kolumny tabeli zostaną zdefiniowane przed zdefiniowaniem procedury składowanej, która się do nich odwołuje.
Poniżej znajduje się kanoniczny przykład kodu SQL utworzonego przez C #, który „ilustruje” problem, który próbuję rozwiązać.
--Say this table already exists.
CREATE TABLE myTable
(
a NVARCHAR(MAX)
)
GO
--My C# code creates something like this
BEGIN TRAN
GO
--the stored procedure gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
SELECT a,b FROM myTable
END
--then the table update
ALTER TABLE myTable
ADD b nvarchar(MAX)
COMMIT TRAN
Możliwe jest , że naprawię to w kodzie C #, ale mam nadzieję na proste „magiczne” ulepszenie, które mogę pobrać z SQL. Zaoszczędzi mi to dużo czasu.
źródło
Odpowiedzi:
Nie.
Czuję się naprawdę winny, pisząc to, ale nie, niestety. Po raz pierwszy usłyszałem o tym przypadku użycia i ma to sens. Najlepiej przesłać prośbę o to na http://connect.microsoft.com, a twoje wnuki będą mogły to zrobić. ;-)
źródło
Na wypadek, gdybyś był nadal zainteresowany, istnieje potencjalne obejście, które możesz zastosować. Oto zaktualizowany kod, który wprowadza
#deferResolution
tabelę tymczasową do każdego zapytania w procedurze. Ponieważ tabela tymczasowa będzie istnieć tylko w czasie wykonywania, procedura jest w stanie skompilować, nawet jeśli odpowiednie kolumny jeszcze nie istniejąmyTable
.Otrzymasz nawet ten sam plan wykonania (bez odniesienia do
#deferResolution
tabeli) dla każdej instrukcji w procedurze, ponieważ optymalizator zapytań może udowodnić, żeWHERE NOT EXISTS
zawsze ocenia to jako prawdziwe.To powiedziawszy, jest to okropny hack prezentowany głównie z myślą o interesie intelektualnym i może się zdarzyć, że załamie się. Jak wspomina Aaron, prawdopodobnie lepiej byłoby wprowadzić wszystkie zmiany schematu we właściwej kolejności.
źródło