2010-03-11 14 views
7

Quando si verifica questo errore, la prima cosa che si chiede è, quale colonna? Sfortunatamente, SQL Server è nessun aiuto qui. Quindi inizi a fare tentativi ed errori. Beh, in questo momento ho una dichiarazione come:La stringa oi dati binari verrebbero troncati - Problema di Heisenberg

INSERT tbl (A, B, C, D, E, F, G) 
SELECT A, B * 2, C, D, E, q.F, G 
    FROM tbl 
     ,othertable q 
WHERE etc etc 

Nota che

  • Alcuni valori vengono modificati o collegati in da un altro tavolo, ma la maggior parte dei valori stanno venendo dal la tabella originale, in modo da non può davvero causare il troncamento risalendo allo stesso campo (che io sappia).
  • campi Eliminare uno alla volta alla fine fa l'errore di andare via, se lo faccio in modo cumulativo, ma — ed ecco il kicker — non importa che i campi Elimino. È come se SQL Server si opponga alla lunghezza totale della riga, che dubito, dal momento che ci sono solo circa 40 campi in tutto e niente di grande.

Qualcuno l'ha mai visto prima?

Grazie.

UPDATE: Ho anche eseguito test "orizzontali", filtrando SELECT, con lo stesso risultato. In altre parole, se io dico

  • WHERE id tra 1 e 100: Errore
  • WHERE id compreso tra 1 e 50: nessun errore
  • WHERE id tra 50 e 100: Nessun errore

Ho provato molte combinazioni e non può essere limitato a una singola riga.

+0

Come aiutante di debug: è possibile provare a scrivere un cursore che superi la tabella di origine e inserisca le righe una alla volta. Forse l'errore si trova in una delle file? – Tomalak

+0

Quali sono i vincoli chiave foriegn? Ci sono? –

+0

@Vecdid - No, non ci sono vincoli di alcun tipo, nemmeno una chiave primaria. È solo una copia usa e getta di una tabella remota, utilizzata solo durante questa routine, creata da SELECT * INTO. – harpo

risposta

5

Anche se la tabella non aveva chiavi, vincoli, indici o trigger, lo ha avuto statistiche e in ciò si pone il problema. Ho ucciso tutte le statistiche della tabella utilizzando questo script

http://sqlqueryarchive.blogspot.com/2007/04/drop-all-statistics-2005.html

E voilà, l'inserto è tornato a funzionare benissimo. Perché le statistiche causano questo errore? Non lo so, ma questo è un altro problema ...

UPDATE: Questo errore è tornato anche con le statistiche cancellate. Perché ero convinto che il messaggio stesso è stato impreciso (non ci sono prove di troncamento), sono andato con this solution invece:

SET ANSI_WARNINGS OFF 
INSERT ... 
SET ANSI_WARNINGS ON 

Va bene, è più di un hack che una soluzione, ma mi permette — e, si spera qualcun altro — per passare ad altre cose.

+0

Perché la lunghezza totale degli attributi delle statistiche era probabilmente maggiore di [900 byte] [1]? Non sono sicuro che questo si applichi alle statistiche e non ne sono convinto. Hai un riferimento per favore, perché mi piacerebbe sapere perché le statistiche tronceranno quando sono semplicemente istogrammi binari (IIRC) – gbn

0

Se si assomiglia a "lunghezza totale", si dispone di trigger di controllo che concatena le colonne per la registrazione?

Edit: dopo l'aggiornamento, mi piacerebbe davvero prendere in considerazione il fatto di avere un innesco causando questo ...

Edit 2, dopo aver visto la tua risposta statistiche ...

Perché le statistiche totali attributo di lunghezza era probabilmente maggiore di 900 bytes? Non sono sicuro che questo si applichi alle statistiche e non ne sono convinto.

Avete un riferimento si prega perché mi piacerebbe sapere il motivo per cui le statistiche avrebbero troncano quando sono istogrammi semplicemente binari (IIRC)

+0

Sto controllando con il dba, ma non ci credo. Ciò significherebbe che è in realtà il * log * in cui viene generato l'avviso di troncamento? – harpo

+0

tabella dei registri, non registro delle transazioni. Ad esempio "OrderHistory" abbinato alla tabella "Ordine" – gbn

0

Sì, quando mi sono imbattuto in questo, ho dovuto creare un altro tavolo/tavoli che imitano la struttura attuale. Quindi non ho modificato il codice, ma ho cambiato le dimensioni dei tipi di dati in tutti i nvarchar (MAX) per ogni campo finché non si è fermato, quindi li ho eliminati uno per uno. Sì, a lungo e trascinato fuori ma ho avuto grossi problemi cercando qualcos'altro. Una volta che ho provato un sacco di cose che mi causavano troppo mal di testa, ho deciso di seguire l'approccio "Uomo delle caverne" mentre ne abbiamo riso in seguito.

Inoltre ho visto un problema simile con FKS, dove si deve chiedere:

Quali sono i vincoli di chiave foriegn? Ci sono?

Dal momento che non ci sono, provare componente DataMgr di questo ragazzo:

http://www.bryantwebconsulting.com/blog/index.cfm/2005/11/21/truncated

verificare anche questo:

http://forums.databasejournal.com/showthread.php?t=41969

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=138456

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=97349

Si può anche eseguire il dump della tabella da cui si sta selezionando una tabella temporanea e scoprire quale riga dà l'errore se si commette l'errore su una tabella temporanea.

Dovrebbe dirti la riga dell'errore, se metti ogni colonna su un'altra linea, dovrebbe dirti esattamente dove sta bombardando.

0

Esiste un limite massimo per le righe in SQL Server 2005. Vedere here.

La maggior parte delle volte si imbatterà in questo w/molte colonne nvarchar.

1

C'è un motivo non si può semplicemente lanciare i campi come l'equivalente della struttura della loro colonna di destinazione in questo modo:

Select Cast(A as varchar(42)) 
, Cast(B * 2 as Decimal(18,4)) 
, Cast(C As varchar(10)) 
... 
From Table 

Lo svantaggio di questo approccio è che tronca i valori di testo al loro carattere limite. Tuttavia, se sei "sicuro" che ciò non dovrebbe accadere, allora non arriverà alcun danno.

+0

Ho esaminato i dati manualmente e non c'è un singolo valore che dovrebbe causare l'errore. Ho controllato il MAX (LEN()) di ogni colonna varchar rispetto alle dimensioni del campo di ricezione, così come tutti i valori numerici. Chiaramente qualcos'altro è al lavoro qui, semplicemente non so cosa. – harpo

+0

Quindi provare a trasmettere tutte le colonne alle specifiche del tipo di dati della tabella di destinazione e verificare se la query verrà eseguita. – Thomas

+0

Oppure impostare ANSI_WARNINGS su OFF e quindi eseguire il confronto con SELECT originale con l'operatore EXCEPT per vedere cosa non è stato inserito come previsto. –

1

In alcuni casi è possibile riscontrare un problema se si dispone di un'altra colonna con valori predefiniti che potrebbe causare il problema.

Es. potresti aver aggiunto una colonna per tracciare l'utente che ha creato la riga, come USER_ENTERED con il valore predefinito di suser_sname() ma la lunghezza della colonna è inferiore al nome utente corrente.

Problemi correlati