Néhány lekérdezést automatikusan generálok a távoli Pg adatbázisból a SELECT-be írt kóddal, és beillesztek egy helyi SQL Server adatbázisba. Egyikük azonban ezt a hibát generálja:
[Microsoft] [ODBC SQL Server illesztőprogram] [SQL Server] A karakterláncot vagy bináris adatokat csonkítják. (SQL-22001) [állapot 22001 volt most 01000]
[Microsoft] [ODBC SQL Server illesztőprogram] [SQL Server] A utasítás megszűnt. (SQL-01000) a. \ Insert.pl 106. sorban.
Hogyan tudom megtudni, hogy melyik oszlop generálja ezt a hibát, és hiányzik-e a bemenet? Van-e mód erre anélkül, hogy nyers erő kitalálná az összes varchar
-t?
Válasz
Nem, nincs bejelentkezve sehova. Menjen el szavazni, és ismertesse üzleti ügyét; ez szerepel az SQL Serverben kijavítandó dolgok hosszú listáján.
Ezt évekkel ezelőtt kérték a Connect-en (valószínűleg először az SQL Server 2000 vagy 2005 időkeretében), majd újra az új visszacsatolási rendszerről:
És most már a következő verziókban került kiszállításra:
Az SQL Server 2019 legelső nyilvános CTP-jében csak a 460 nyomjelző alatt jelenik meg. Ez titokban hangzik, de a ez a Microsoft folyóirat . Ez lesz az alapértelmezett viselkedés (nincs szükség nyomkövetési jelzőre) a továbbiakban, bár ezt egy új adatbázis-hatókörű konfigurációval vezérelheti VERBOSE_TRUNCATION_WARNINGS
.
Itt egy példa:
USE tempdb; GO CREATE TABLE dbo.x(a char(1)); INSERT dbo.x(a) VALUES("foo"); GO
Eredmény az SQL Server 2019 előtti összes támogatott verzióban:
Msg 8152, 16. szint, 30. állapot, 5. sor
A karakterlánc- vagy bináris adatok csonkolásra kerülnek.
Az utasítás megszűnt.
Most, az SQL Server 2019 CTP-n, engedélyezve a nyomkövetési jelzőt:
DBCC TRACEON(460); GO INSERT dbo.x(a) VALUES("foo"); GO DROP TABLE dbo.x; DBCC TRACEOFF(460);
Az eredmény a táblázatot, az oszlopot és a ( csonka , teljes ) érték:
2628. üzenet, szint 16. állapot, 1. állapot, 11. sor
A karakterláncot vagy bináris adatokat a “tempdb.dbo.x” táblázat “a” oszlopában csonkolják meg. Csonka érték: “f”.
A nyilatkozat megszűnt.
Amíg át nem tud lépni egy támogatott verzióra / CU-ra vagy az Azure SQL Database-re, addig módosíthatja a “automagikus” kód a max_length tényleges kihúzásához a következőből: sys.columns
, a névvel együtt, amelyet mindenképpen el kell érnie, majd alkalmazza az LEFT(column, max_length)
vagy bármilyen PG-vel egyenértékű is. Vagy, mivel ez csak azt jelenti, hogy csendben elveszíti az adatokat, keresse meg, hogy milyen oszlopok nem egyeznek, és javítsa ki a céloszlopokat, hogy azok illeszkedjenek a forrás összes adatához. Tekintettel a metaadatokhoz való hozzáférésre mindkét rendszerhez, és az a tény, hogy már ír egy olyan lekérdezést, amelynek automatikusan meg kell egyeznie a forrás -> cél oszlopokkal (különben ez a hiba aligha jelentené a legnagyobb problémát), akkor nem kell semmiféle nyers erőt megtennie találgatás.
Válasz
Ha van hozzáférése az SQL Server Import and Export Wizard futtatásához Az SQL Server Management Studio alkalmazásból (kattintson a jobb gombbal az adatbázis> Feladatok> Adatok importálása …) elemre, és hozzon létre egy feladatot, amelyet az SQL Client alkalmazásból importál, a lekérdezés adatforrásként a céltáblába.
Mielőtt futtatná az importálást, áttekintheti az adatok hozzárendelését, és megmondja, mely oszlopok vannak ellentmondásos mezőtípusokkal. Ha pedig futtatja az importálási feladatot, akkor megmondja, hogy mely oszlopokat nem sikerült importálni.
Mintaellenőrzési figyelmeztetés:
0x802092a7 figyelmeztetés: Adatfolyam 1. feladat: Csonkolás előfordulhat, ha a 316 hosszúságú “NARRATIVE” adatfolyam oszlopból adatot beszúrunk a 60 hosszú “NARRATIVE” adatbázis oszlopba. (SQL Server Import and Export Wizard)
Válasz
Végül Microsoft úgy döntött, hogy értelmes információkat szolgáltat a String or binary would be truncated
számára az SQL Server 2016 SP2 CU-tól, az SQL Server 2017 CU12-től és az SQL Server 2019-től kezdődően.
Az információk most már tartalmazza a sértő táblázat oszlopát (teljesen minősített név) és a sértő értéket (csonkítva 120 karakterrel):
2628. üzenet, 16. szint, 1. állapot, Az x sor A karakterláncot vagy a bináris adatokat a “TheDb.TheSchema” tábla csonkolja.TheTable “,” TheColumn “oszlop. Csonka érték:” … “. A utasítás megszűnt.
Válasz
Végül nem találtam módot az oszlopinformációk megszerzésére anélkül, hogy magam írtam volna.
Ezt a hibaüzenetet a DBD::ODBC
, használhatja azonban a sys.columns (max_length)
alkalmazást is (csak nem tudom, hogyan).
Ilyen kódot használtam az oszloplistán, hogy két elemből álló tömbök listáját kapjam, a COLUMN_NAME
és MAX_LENGTH
(dokumentálva: DBI column_info()
).
my @max_lengths = map [ @{$_->fetchall_arrayref->[0]}[3,6] ] , map $dbh_mssql->column_info("database", "dbo", $dest_table, $_) , @col_mssql ;
Ezután kifogtam a INSERT
kivételeket, és kinyomtattam valami hasznosat. Ebben a példában a @$row
a sth->execute()
if ($@) { warn "$@\n"; for ( my $idx=0; $idx <= $#{ $row }; $idx++ ) { Dumper { maxlength => $max_lengths[$idx]->[1] , name => $max_lengths[$idx]->[0] , length => length( $row->[$idx] ) , content => $row->[$idx] }; } die; }
Emellett kérjük, szavazzon, és szavazzon felül a másik válaszra
sys.columns
, mert fogalmam sem volt róla, hogy jelenleg melyik kódot használja a automatikusan ” generálja a lekérdezéseket. Valójában nem ‘ nincs túl bonyolultabb, mint azt aSELECT name, object_id, max_length FROM sys.columns;
-nél tudnám kitalálni a kódba való beépítésről. Mivel már rendelkezik olyan automag kóddal, amely ezt biztosan megcsinálja – vagy valami nagyon hasonlót -, nem gondoltam ‘ nem gondoltam, hogy erre példa lenne szükséges.sys.columns
hogyan működik két oszloppal, amelyek azonosakname
. Ezenkívül a könyvtár használatával működtem, nem pedigsys
, miért tenném ezt választott válaszként? AzMicrosoft SQL doesn't have x, do y instead
érvényes hozzájárulás, de ha ay
értéke alacsonyabb ay
-nél, akkor ‘ mást fogok csinálni, és megjelölni választottként.