Kuinka tunnistan sarakkeet, jotka ovat vastuussa “ -merkkijonosta tai binaaritiedoista katkaistaan. ”

Luon joitain kyselyjä automaattisesti koodilla, jonka kirjoitin SELECT: ään etätunnuksen Pg-tietokannasta ja lisätään paikalliseen SQL Server -tietokantaan. Yksi niistä tuottaa kuitenkin tämän virheen:

[Microsoft] [ODBC SQL Server Driver] [SQL Server] Merkkijono tai binääridata katkaistaan. (SQL-22001) [tila oli 22001 nyt 01000]

[Microsoft] [ODBC SQL Server Driver] [SQL Server] Lause on lopetettu. (SQL-01000). \ Insert.pl -rivillä 106.

Kuinka saan selville, mikä sarake tuottaa kyseisen virheen ja puuttuu panos? Onko mahdollista tehdä tämä ilman raakaa voimaa arvaamaan kaikki varchar?

Vastaus

Ei, sitä ei ole kirjattu mihinkään. Mene äänestämään ja kerro yrityksesi asia; tämä on yksi pitkästä luettelosta asioista, jotka tulisi korjata SQL Serverissä.

Tätä pyydettiin vuosia sitten Connectissa (todennäköisesti ensin SQL Server 2000: n tai 2005: n aikataulussa), sitten taas uudessa palautejärjestelmässä:

Ja nyt se on toimitettu seuraavina versioina:

SQL Server 2019: n ensimmäisessä julkisessa CTP: ssä se tulee näkyviin vain jälkilipun 460 alle. Tämä kuulostaa tavallaan salaiselta, mutta se julkaistiin julkaisussa tämä Microsoftin julkaisu . Tämä on oletuskäyttäytyminen (jälkilippua ei vaadita) jatkossa, vaikka voit hallita sitä uudella tietokannan kattavalla kokoonpanolla VERBOSE_TRUNCATION_WARNINGS.

Täällä on esimerkki:

USE tempdb; GO CREATE TABLE dbo.x(a char(1)); INSERT dbo.x(a) VALUES("foo"); GO 

Tulos kaikissa tuetuissa versioissa, jotka edeltävät SQL Server 2019:

Viesti 8152, taso 16, tila 30, rivi 5
Merkkijono- tai binääridata katkaistaan.
Lause on lopetettu.

Nyt SQL Server 2019: n CTP: ssä, kun jäljityslippu on käytössä:

DBCC TRACEON(460); GO INSERT dbo.x(a) VALUES("foo"); GO DROP TABLE dbo.x; DBCC TRACEOFF(460); 

Tulos näyttää taulukon, sarakkeen ja ( katkaistu , ei täysi ) arvo:

Viesti 2628, taso 16, tila 1, rivi 11
Merkkijono- tai binääridata katkaistaan taulukon ”tempdb.dbo.x” sarakkeessa ”a”. Katkaistu arvo: ”f”.
Lausunto on lopetettu.

Kunnes voit siirtyä tuettuun versioon / käyttöjärjestelmään tai siirtyä Azure SQL -tietokantaan, voit muuttaa ”automagic” -koodi, jolla max_length voidaan todella vetää kohdasta sys.columns, yhdessä sen nimen kanssa, jonka sinun on silti päästävä sinne, ja sitten LEFT(column, max_length) Tai mikä tahansa PG: n vastaavuus on. Tai koska se tarkoittaa vain, että menetät tietoja hiljaa, mene selvittämään, mitkä sarakkeet eivät täsmää, ja korjaa kohdesarakkeet siten, että ne sopivat kaikkiin lähteen tietoihin. Kun otetaan huomioon metatietojen käyttöoikeus molempiin järjestelmiin ja se, että kirjoitat jo kyselyä, jonka on vastattava automaattisesti lähdekoodia -> kohdesarakkeita (muuten tämä virhe tuskin olisi suurin ongelma), sinun ei tarvitse tehdä mitään raaaa voimaa arvaa ollenkaan.

Vastaa

Jos sinulla on pääsy SQL Server Import and Export Wizard -toiminnon suorittamiseen luo SQL Server Management Studiosta (napsauta hiiren kakkospainikkeella tietokantaa> Tehtävät> Tuo tietoja …), luo tehtävä, joka tuo SQL-asiakkaasta käyttämällä kyselyäsi tietolähteenä kohdetaulukkoon.

Ennen tuonnin suorittamista voit tarkistaa tietojen yhdistämisen ja kertoa, millä sarakkeilla on epäjohdonmukaiset kenttätyypit. Ja jos suoritat tuontitehtävän, se kertoo, mitkä sarakkeet ei tuonnissa.

Vahvistamisen esimerkkivaroitus:

Varoitus 0x802092a7: Tietovirtatehtävä 1: Katkaisu saattaa johtua siitä, että tietoja lisätään 316-pituisista tietovirtasarakkeista ”KERROSTI” 60-tietokannan sarakkeeseen ”KERROSTI”. (Ohjattu SQL Serverin tuonti- ja vientitoiminto)

Vastaa

Lopuksi Microsoft on päättänyt antaa mielekkäitä tietoja diviville String or binary would be truncated alkaen SQL Server 2016 SP2: n CU: sta, SQL Server 2017 CU12: sta ja SQL Server 2019: stä.

Tiedot sisältää nyt sekä loukkaavan taulukon sarakkeen (täysin määritelty nimi) että loukkaavan arvon (katkaistu 120 merkillä):

Viesti 2628, taso 16, tila 1, Rivi x Merkkijono tai binääridata katkaistaan taulukossa ”TheDb.TheSchema.TheTable ”, sarake” TheColumn ”. Katkaistu arvo:” … ”. Lauseke on lopetettu.

Vastaa

Viime kädessä en löytänyt tapaa saada saraketietoja kirjoittamatta niitä itse.

Tämän virhesanoman on luonut DBD::ODBC , voit kuitenkin käyttää myös sys.columns (max_length) (en vain tiedä miten).

Käytin tällaista koodia sarakeluettelossani saadaksesi luettelon matriiseista, joissa on kaksi elementtiä, COLUMN_NAME ja MAX_LENGTH (dokumentoitu DBI column_info() ).

my @max_lengths = map [ @{$_->fetchall_arrayref->[0]}[3,6] ] , map $dbh_mssql->column_info("database", "dbo", $dest_table, $_) , @col_mssql ; 

Sitten sain kiinni INSERT -kohdan poikkeukset ja tulosti jotain hyödyllistä. Tässä esimerkissä @$row on tiedot, jotka lähetetään osoitteeseen 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; } 

Äänestäkää ja äänestäkää toinen vastaus myös

Kommentit

  • I didn ’ ei laittanut mitään koodiviittausta sys.columns, koska minulla ei ollut aavistustakaan, mitä koodia käytät tällä hetkellä ” luo kyselysi automaattisesti ”. Ei todellakaan ole ’ t liian monimutkaista, mitä voisin arvata sisällyttämisestä koodiin kuin SELECT name, object_id, max_length FROM sys.columns;. Koska sinulla on jo automaattinen koodi, joka täytyy tehdä tämä – tai jotain sen kaltaista – en ajatellut ’, että esimerkki oli mielestäni tarpeellinen.
  • I ’ en ole varma, kuinka sys.columns toimii kahden sarakkeen kanssa, joilla on sama name. Lisäksi sain asian toimimaan käyttämällä kirjastoa sys -sivuston sijaan, miksi tekisin sen valituksi vastaukseksi? Microsoft SQL doesn't have x, do y instead on kelvollinen lahjoitus, mutta jos y on huonompi kuin y, ’ aion tehdä jotain erilaista ja merkitä sen valituksi.
  • Kysymyksesi oli pohjimmiltaan miten saan selville mikä sarake tuotti virheen (oletettavasti , joten voit korjata yhden paikan sen sijaan, että suunnittelet ratkaisua uudelleen). Sanoin, mistä etsiä: sys. Sarakkeet. Mihin sinun pitäisi etsiä verrata lähdesarakkeen pituutta kohdesarakkeen pituuksiin. Kuinka teet sen, on sinun tehtäväsi. En sanonut ’ en kertonut kuinka korjata koodisi, koska minulla ei ole aavistustakaan kuinka automaattista kyselyäsi alun perin luotiin, joten, kuten sanoin, ei ollut aavistustakaan kuinka lisätä pituusmääritykset mihin tahansa kyselyyn, jolla sinulla jo oli.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *