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
IDENTITYtulajdonságát átviszik, de nem, ha:- A
SELECTutasítás összekapcsolt táblákat tartalmaz (vagyJOIN, vagyUNION),GROUPBYzáradék vagy összesített függvény.Ha el kell kerülnie, hogy egyIDENTITYtulajdonság átkerüljön az új táblába, de szüksége van az oszlop értékeire, akkor érdemes egyJOINa table-source-ba egy olyan feltétel mellett, amely soha nem igaz, vagy egyUNION-hez, amely nem ad sorokat. - A
IDENTITYoszlop többször szerepel aSELECTlistában - A
IDENTITYoszlop része egy kifejezés - A
IDENTITYoszlop távoli adatforrásból származik
- A
- Nem lehet
SELECT…INTOaká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
ONzáradékon keresztül meg lehet adni azt a fájlcsoportot, amelyben a céltábla létrejön. - Megadhat egy
ORDERBYzáradék, de általában figyelmen kívül hagyják. Emiatt aIDENTITY_INSERTsorrendje nem garantált. - Ha egy számított oszlop szerepel a
SELECTlist, az új táblázat megfelelő oszlopa nem számított oszlop. Az új oszlopban szereplő értékek azok az értékek, amelyeket aSELECT…INTOvégrehajtásakor számítottak ki. - Mint egy
CREATETABLEutasítás, ha egySELECT…INTOutasí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.