2012-03-12 15 views
5

Ho una vista dati complessa che collega e riassume ricorsivamente le informazioni.Come posso ignorare gli errori relativi a "Overflow aritmetico" all'interno di una visualizzazione dati?

Ogni notte un'operazione pianificata esegue una stored procedure che seleziona tutti i dati dalla visualizzazione dati e la inserisce in una tabella in modo che gli utenti possano eseguire query e analizzare i dati molto più rapidamente rispetto all'esecuzione di un'istruzione select sui dati vista.

La tabella padre è composta da poche centinaia di migliaia di record e il set di risultati dell'esportazione è di oltre 1.000.000 di record.

Per quasi tutte le notti il ​​processo di esportazione funziona senza problemi, tuttavia, se un utente immette un valore errato nel nostro sistema ERP master, arresta il processo notturno perché uno dei campi decimali conterrà un valore che non rientrare in alcune delle conversioni che devo apportare sui dati. Eseguire il debug e trovare il campo specifico e errante può essere molto difficile e richiedere molto tempo.

Detto questo, ho letto le due impostazioni SQL NUMERIC_ROUNDABORT e ARITHABORT. Queste sembrano le opzioni perfette per risolvere il mio problema, tuttavia, non riesco a convincerle a lavorare con la mia vista dati o la stored procedure.

La mia stored procedure non è altro che un'istruzione TRUNCATE e INSERT. Ho aggiunto ...

SET NUMERIC_ROUNDABORT OFF 
SET ARITHABORT OFF 

... all'inizio della SP e che non ha aiutato. Presumo che questo sia dovuto al fatto che l'errore sta avvenendo tecnicamente dal codice associato alla vista dati.

Successivamente, ho provato ad aggiungere due proprietà estese alla Vista dati, sperando che funzionasse. Non è stato così.

Esiste un modo per impostare queste proprietà SQL in modo da ignorare gli errori di arrotondamento in modo che sia possibile esportare i dati dalla visualizzazione dati?

So per la maggior parte di noi, come rispondenti SO, la nostra prima inclinazione è chiedere il codice. In questo caso, tuttavia, il codice è estremamente complesso e proprietario. So che fissare le definizioni che causano l'overflow occasionale è la soluzione ideale, ma in questa circostanza è molto più efficiente ignorare questo tipo di errori perché si verificano su una base così rara e sono così difficili da risolvere.

Cosa posso fare per ignorare questo comportamento?

UPDATE

Per caso, credo che avrei potuto trovato la causa principale del problema, tuttavia, non ho idea del perché questo sarebbe stato in corso. Non fa da allora.

Attraverso la mia vista tabella, ho vari campi che vengono calcolati. Poiché questi campi devono essere inseriti nei campi all'interno della tabella definiti come decimal (12, 5), imposto sempre le istruzioni del campo di visualizzazione in clausole CAST(... AS DECIMAL(12, 5)).

Per caso, mi sono imbattuto in una stranezza. Ho deciso di vedere in che modo il SSMS "ha visto" la mia vista dei dati. Nell'Explorer oggetti SSMS, ho ampliato la sezione Viste -> [La mia vista] -Colonne e ho visto che uno dei campi era definito come decimal (13, 5).

ho pensato che devo aver fatto un errore in una delle mie affermazioni di fusione ma dopo aver cercato in tutto il codice per la visualizzazione della tabella, non esiste una definizione per un campo decimal(13, 5) ?! La mia unica ipotesi è che la definizione che SSMS vede del campo vista deve essere derivata dai dati risultanti. Tuttavia, non ho idea di come ciò possa accadere poiché ogni campo è un decimal(12, 5).

vorrei sapere perché questo sta accadendo ma, ancora una volta, la mia domanda iniziale si è fermato. Come e quale istruzione SET posso definire su una vista tabella che ignorerà tutti gli overflow aritmetici e scriverà un valore nullo nei campi con dati errati?

COMMENTI FINALI

Ho segnato la risposta di HeavenCore come la risposta perché non affrontare la mia domanda, ma non ha risolto il mio problema di fondo.

Dopo un po 'di risoluzione dei problemi e tentativi di cercare di ottenere la mia esportazione al lavoro, io sto andando a tentare un approccio diverso. Non riesco ancora a far funzionare l'esportazione, anche se imposto le proprietà NUMERIC_ROUNDABORT e ARITHABORT su OFF.

+0

Perché ciò stia accadendo Il valore deve essere sempre espressi a un diverso tipo di dati da cui è conservato? Supponendo che questo sia il caso, il casting viene eseguito a livello di insert o select prima di inserire il livello? Ad esempio, la vista genera un errore se la selezioni manualmente con alcuni dati non autorizzati? (ad esempio, stai trasmettendo una colonna a un INT all'interno della vista? L'overflow potrebbe esserci in quel posto anziché l'inserto?) - Se la vista seleziona bene, potresti rivedere la tua istruzione INSERT ... SELECT per escludere determinati valori basati su LEN()? – HeavenCore

+0

L'errore si verifica se SELEZIONA i dati dalla visualizzazione dati. Ci sono istruzioni cast all'interno della visualizzazione dati. Questo casting è obbligatorio e accade dopo che l'aritmetica ha avuto luogo sul campo. – RLH

+0

Se ignori il VIEW per ora ed esegui manualmente l'istruzione SELECT all'interno della vista con SET SET NUMERIC_ROUNDABORT OFF e SET SET ARITHABORT OFF, la query funziona? (nota che SSMS imposta queste impostazioni in modo invisibile quando apri una nuova finestra di query, controlla le opzioni SSMS) – HeavenCore

risposta

4

Credo ARITHABORT è tuo amico qui.

Ad esempio, utilizzando SET ARITHABORT OFF & SET ANSI_WARNINGS OFF sarà NULL i valori che non riesce a lanciare (invece di eccezioni da lancio)

Ecco un rapido esempio:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[tbl_OverflowExample](
    [Value] [decimal](12, 2) NULL 
) ON [PRIMARY]  
GO 
INSERT [dbo].[tbl_OverflowExample] ([Value]) VALUES (CAST(9999999999.00 AS Decimal(12, 2))) 
GO 
INSERT [dbo].[tbl_OverflowExample] ([Value]) VALUES (CAST(1.10 AS Decimal(12, 2))) 
GO 

--#### Select data without any casting - works 
SELECT VALUE 
FROM dbo.tbl_OverflowExample 

--#### With ARITHABORT and ANSI warnings disabled - Returns NULL for 999999 but 1.10 as expected 
SET ARITHABORT OFF; 
SET ANSI_WARNINGS OFF; 
SELECT CONVERT(DECIMAL(3, 2), VALUE) 
FROM dbo.tbl_OverflowExample 
GO 

--#### With defaults - Fails with overflow exception 
SET ARITHABORT ON; 
SET ANSI_WARNINGS ON; 
SELECT CONVERT(DECIMAL(2, 2), VALUE) 
FROM dbo.tbl_OverflowExample 

Personalmente, però - preferirei eseguire il debug della vista e utilizzare alcune istruzioni CASE /.../ END per restituire NULL se il valore sottostante è maggiore del tipo di dati di destinazione: ciò garantisce che la visualizzazione funzioni indipendentemente dalle opzioni di connessione.

EDIT: corretto alcuni errori di fatto

+0

Potrebbe aggiungere una sezione "Nel caso in cui è necessario utilizzare queste impostazioni"? Il mio problema è che non riesco a capire come definire un'istruzione 'SET' in una vista. Sì hai ragione. I campi fasulli restituiranno un valore NULL. Ma nel caso di questi dati, è importante che sia disponibile ogni giorno, ma questi dati vengono utilizzati principalmente per stime ravvicinate e con 1.000.000 di documenti restituiti, è OK se 1 non è corretto per un paio di settimane, ogni pochi mesi. – RLH

+0

Si dice che l'inserimento da select è eseguito da un'attività sceduled?dovresti semplicemente modificare l'attività per chiamare 'SET ARITHABORT OFF;' & 'SET ANSI_WARNINGS OFF;' prima di eseguire il comando EXEC. Assumendo il lavoro di SQL Server Agent, avresti 1 step come segue: 'SET ARITHABORT OFF; SET ANSI_WARNINGS OFF; EXEC usp_Whatever; ' – HeavenCore

+0

Inoltre, ho provato molti dei tuoi suggerimenti. Il problema è che di solito riesco a trovare la riga specifica che non riesce ma non riesco a trovare il punto di errore nella matematica o, necessariamente, quale colonna. Ci sono molte formule e dichiarazioni cast in questa vista. Molte delle dichiarazioni cast sono per impedire che questo tipo di cose si verifichi ancora, tuttavia, si insinua circa una volta ogni 6 mesi. Trovare la riga del problema e risolverlo può richiedere fino a un giorno intero e fissare i dati sottostanti non è così importante. Ecco perché preferirei ignorare questi errori, se possibile. – RLH

Problemi correlati