Mikor kell használni a SELECT… INTO utasítást (PE003)
Használhatjuk az SELECT…INTO
-t az SQL Server szolgáltatásban, hogy új táblázatot hozzunk létre egy táblázatforrásból. Az SQL Server az SELECT
listában szereplő kifejezések attribútumait használja az új tábla felépítésének meghatározására.
Az SQL Server 2005 előtt használja a SELECT…INTO
a termelési kódban teljesítmény-kódszag volt, mert sémazárakat szerzett az adatbázis rendszertábláin, ami az SQL Server válaszképtelenségét okozta a lekérdezés végrehajtása közben. Ez azért van, mert DDL utasítás egy implicit tranzakcióban, amely elkerülhetetlenül hosszú ideig tart, mivel az adatokat ugyanabba az SQL utasításba illesztik be. Ezt a viselkedést azonban kijavították az SQL Server 2005-ben, amikor a zárolási modell megváltozott.
SELECT…INTO
azért vált népszerűvé, mert gyorsabb volt az adatok beszúrása, mint a INSERT
INTO…SELECT…
. Ennek oka elsősorban az volt, hogy a SELECT…INTO
műveletet lehetőség szerint tömegesen naplózták. Bár a INSERT
INTO
mostantól tömegesen is naplózható, mégis láthatja ezt a teljesítményelőnyt az SQL Server 2012-ben és 2014-ben, mert a SELECT…INTO
párhuzamosítható ezeken a verziókon, míg a INSERT
INTO
párhuzamosításának támogatása csak az SQL Serverben jelent meg 2016. Azonban a SELECT…INTO
alkalmazással továbbra is az a feladata, hogy meghatározza az összes szükséges indexet és korlátozást, és így tovább az új táblán.
Ajánlás kerülje a SELECT…INTO
használatát, a termelési kódhoz kódelemzési szabályként szerepel az SQL Prompt (PE003).
Táblázatok létrehozása a SELECT INTO utasítással
Az SQL Server SELECT…INTO
funkcióját úgy tervezték, hogy egy folyamat részeként egy táblázati forrást tároljon vagy ‘fennmaradjon’. Itt van egy egyszerű példa:
A tábla forrása azonban sok más lehet, mint a hagyományos tábla, például egy felhasználó által definiált függvény, egy OpenQuery
, egy OpenDataSource
, egy OPENXML
záradékot, származtatott táblázatot, összekapcsolt táblázatot, elfordított táblázatot, távoli adatforrást, táblázatváltozót vagy változó függvény. Ezekkel az egzotikusabb táblázatforrásokkal válik hasznosabbá a SELECT…INTO
szintaxis.
KIVÁLASZTHATÓ az ANSI részébe standard?
Az ANSI szabványok valóban támogatnak egy SELECT…INTO
konstrukciót; ezt singleton selectnek hívják, és egyetlen sort tölt be értékekkel, de nagyon ritkán használják (Köszönet Joe Celkónak, hogy ezt rámutatta).
Az emberek gyakran használják a SELECT…INTO
-et azzal a félreértéssel, hogy ez a táblázatok másolásának gyors módja, és ezért meglepő, hogy a (z) a forrás táblázat átkerül az új táblába. Ezeket a SELECT…INTO
utasításban sem lehet megadni. Nem tesz semmit sem a semmisséggel, sem a számított oszlopok megőrzésével. Ezeket a feladatokat visszamenőlegesen kell elvégezni a rendelkezésre álló adatokkal, ami elkerülhetetlenül időt vesz igénybe.
Használhatja azonban a IDENTITY
függvényt (adattípus, seed, növekmény) identitásmező beállításához, és ha a forrás egyetlen tábla, akkor a céltábla oszlopát identitásoszlopokká lehet tenni. Ez a tény valószínűleg arra készteti a fejlesztőket, hogy feltételezzék, hogy más oszlopattribútumokat továbbítanak.
Ezenkívül nem hozhat létre particionált táblákat, ritka oszlopokat vagy más, a forrástáblától örökölt attribútumokat. Hogyan történhet, amikor az adatok sok összekapcsolást tartalmazó lekérdezésből származhatnak, vagy valamilyen egzotikus külső adatforrásból származnak?
Mivel az SQL 2012 SP1 CU10, SELECT…INTO
párhuzamosan kell végrehajtani, Az SQL Server 2016 óta azonban a párhuzamos beillesztés megengedett a hagyományos INSERT INTO…SELECT
utasításon, bizonyos korlátozásokkal, így a … INTO
most meglehetősen csökkent. A INSERT
INTO
folyamat is felgyorsítható, ha a helyreállítási modell beállításával tömeges naplózásra van lehetőség, nem pedig teljes helyreállításra. egyszerű vagy tömeges naplózással, beillesztve egy üres táblába vagy egy halomba, és beállítva a TABLOCK
tippet a táblához.
Az alábbiakban összefoglalunk néhány korlátozást és korlátozások a SELECT…INTO
használatakor.
- Az oszlop
IDENTITY
tulajdonságát átviszik, de nem, ha:- A
SELECT
utasítás összekapcsolt táblákat tartalmaz (vagyJOIN
, vagyUNION
),GROUP
BY
záradék vagy összesített függvény.Ha el kell kerülnie, hogy egyIDENTITY
tulajdonság átkerüljön az új táblába, de szüksége van az oszlop értékeire, akkor érdemes egyJOIN
a table-source-ba egy olyan feltétel mellett, amely soha nem igaz, vagy egyUNION
-hez, amely nem ad sorokat. - A
IDENTITY
oszlop többször szerepel aSELECT
listában - A
IDENTITY
oszlop része egy kifejezés - A
IDENTITY
oszlop távoli adatforrásból származik
- A
- Nem lehet
SELECT…INTO
akár táblázatértékű paraméter, akár táblázatváltozó célként, bár kiválaszthatja azokat:FROM
. - Még akkor is, ha a forrás egy particionált tábla, az új tábla az alapértelmezett fájlcsoportban jön létre. Az SQL Server 2017 alkalmazásban azonban a
ON
záradékon keresztül meg lehet adni azt a fájlcsoportot, amelyben a céltábla létrejön. - Megadhat egy
ORDER
BY
záradék, de általában figyelmen kívül hagyják. Emiatt aIDENTITY_INSERT
sorrendje nem garantált. - Ha egy számított oszlop szerepel a
SELECT
list, az új táblázat megfelelő oszlopa nem számított oszlop. Az új oszlopban szereplő értékek azok az értékek, amelyeket aSELECT…INTO
végrehajtásakor számítottak ki. - Mint egy
CREATE
TABLE
utasítás, ha egySELECT…INTO
utasítás egy explicit tranzakcióban található, az érintett rendszertáblák mögöttes sorai kizárólag az ügylet kifejezett elkötelezettségéig zárolva. Időközben ez blokkokat eredményez más folyamatokban, amelyek ezeket a rendszertáblákat használják.
Van némi zavart a SELECT…INTO
ideiglenes táblák használatával. A SELECT…INTO
kissé tisztességtelen hírnevet szerzett ezzel kapcsolatban, de ez egy általánosabb probléma része volt, amely nagy teher alatt tempdb
reteszeléssel járt. kis temp táblázat létrehozása és törlése. Amikor a SELECT…INTO
lelkesen elfogadták, ez nagymértékben növelheti az ilyen típusú tevékenységet. A probléma könnyen megoldható az SQL Server 2000-ben, a TF1118 nyomjelző használatának bevezetésével, amelyre az SQL Server 2016-tól már nincs szükség. A teljes magyarázatért lásd: A TF 1118 körüli tévhitek.
Összegzés
Összefoglalva: SELECT…INTO
jó módszer a táblázat készítéséhez- forrás ideiglenesen állandó a folyamat részeként, ha nem érdekelnek korlátozások, indexek vagy speciális oszlopok. Ez nem jó módszer a táblázat másolására, mert a táblázat sémájának csak a leglényegesebb elemei másolhatók. Az évek során voltak olyan tényezők, amelyek fokozták vagy csökkentették a SELECT…INTO
vonzerejét, de összességében célszerű elkerülni, amikor csak lehetséges. Ehelyett hozzon létre egy táblázatot kifejezetten, a táblázat összes olyan tulajdonságával, amelyek az adatok konzisztenciájának biztosítására szolgálnak.