Hogyan tudom azonosítani azokat az oszlopokat, amelyek felelősek a “ sztringekért vagy a bináris adatokért. ”

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

Hozzászólások

  • I didn ‘ nem tett semmilyen kódot, amelyre hivatkozni kellett volna: 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 a SELECT 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.
  • I ‘ nem vagyok biztos abban, hogy a sys.columns hogyan működik két oszloppal, amelyek azonosak name. Ezenkívül a könyvtár használatával működtem, nem pedig sys, miért tenném ezt választott válaszként? Az Microsoft SQL doesn't have x, do y instead érvényes hozzájárulás, de ha a y értéke alacsonyabb a y -nél, akkor ‘ mást fogok csinálni, és megjelölni választottként.
  • A kérdése lényegében az volt, hogy hogyan tudom megtudni, hogy melyik oszlop generálta a hibát (feltehetően , így kijavíthatná azt az egy helyet, ahelyett, hogy újratervezné a megoldást). Mondtam, hogy hol kell keresni: sys. oszlopok. Amire pontosan érdemes figyelni, hogy összehasonlítsa a forrásoszlop hosszát a céloszlop hosszával. Hogy ezt hogyan csinálod, rajtad múlik. Nem ‘ nem mondtam meg, hogyan javítsd ki a kódodat, mert fogalmam sincs, hogy hogyan jött létre az automagikus lekérdezésed, így, mint mondtam, fogalmam sem volt, hogyan hozzáadni a hosszmeghatározásokat bármilyen lekérdezéshez.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük