2010-10-05 16 views
8

Używam zapytania parametrycznego, aby wstawić wartości do tabeli Oracle, tak:Dlaczego otrzymuję ORA-01722 (nieprawidłowy numer)?

var q = "insert into MyTable(Field1, Field2...) values(:Field1, :Field2...)"; 
var cmd = new OracleCommand(q, conn); // conn is a pre-existing connection 
cmd.Parameters.Add("Field1", field1Val); 
cmd.Parameters.Add("Field2", field2Val); 
// etc... 
cmd.ExecuteNonQuery(); 

Zostało to działa dobrze, ale nagle ten przestał działać, a ja otrzymuję błędu Oracle ORA-01722 (nieprawidłowy numer). Sprawdziłem parametry, a wszystkie liczby są bez wątpienia poprawnymi liczbami. Nawet zastąpiłem wartości pozorne dla dowolnych wartości null i nadal dostaję błąd. Próbowałem tego samego zapytania w bezpośrednim sql (przy użyciu OraDeveloper Studio) i działa, nawet z identycznymi parametrami.

Jak mogę to śledzić?

EDIT: na żądanie w komentarzach, oto CREATE tabela:

CREATE TABLE ALPHA.VISITFINDINGS (
    ID NUMBER(12), 
    VISITID NUMBER(12) NOT NULL, 
    DESCRIPTION VARCHAR2(100), 
    CUSTOMIMAGE CLOB, 
    VISUALFINDINGSSECTIONMAPID NUMBER(12), 
    FINDINGSID NUMBER(12), 
    CONSTRAINT FK_VISITFINDINGS_AREA FOREIGN KEY (VISUALFINDINGSSECTIONMAPID) 
    REFERENCES ALPHA.VISUALFINDINGSSECTIONMAP(VISUALFINDINGSSECTIONMAPID), 
    CONSTRAINT FK_VISITFINDINGS_FINDINGS FOREIGN KEY (FINDINGSID) 
    REFERENCES ALPHA.FINDINGS(FINDINGSID), 
    CONSTRAINT FK_VISITFINDINGS_VISIT FOREIGN KEY (VISITID) 
    REFERENCES ALPHA.VISITS(VISITID), 
    CONSTRAINT PK_VISITFINDINGS PRIMARY KEY (ID)) 
TABLESPACE USERS 
STORAGE (
    INITIAL 64K 
    MAXEXTENTS UNLIMITED 
) 
LOGGING; 
+2

proszę pisać CREATE TABLE dla tabeli. Domyślam się, że wstawiane wartości są większe niż te przydzielone dla danego typu danych. IE: kolumna ma NUMBER (3) i próbujesz wstawić 1000. –

+0

Utwórz opublikowaną instrukcję tabeli. –

Odpowiedz

28

Mam już udzieloną odpowiedź, ale myślę, że warto tutaj wspomnieć o tym, co stanowiło źródło moich problemów, na wypadek gdyby ktoś inny znalazł ten przedmiot, szukając odpowiedzi na swój problem.

Problem polega na tym, że wdrożenie C# od sparametryzowanych kwerend dla Oracle zawiera poważne i potencjalnie niebezpieczny błąd - prawdziwy „pit w domenie publicznej”:

To nie ma znaczenia, co wy nazywacie swoje parametry; należy je dodać w kolejności, w jakiej pojawiają się w zapytaniu.

Zobacz więcej here.

+2

Ponieważ jest to bardziej dokładne, prawdopodobnie powinieneś usunąć zaznaczenie z mojej odpowiedzi i oznaczyć to! – Rup

+0

@Rup - Ty prawy koleś, ty. ;) –

+3

Jest to roszczenie w drugim wątku, to nie jest błąd, ale funkcja. Oczywiście byłaby to funkcja tak niebezpieczna i bezużyteczna, że ​​jest OBU funkcja i błąd. Ale mówią, że jeśli ustawisz wartość OracleCommand.BindByName = true, będzie działać tak, jak powinna. –

5

Kiedy mówisz sprawdzone parametry masz na myśli zbieranie Parameters na klasy SqlCommand? Być może upaść od this note on the SqlParameter page:

Należy zachować ostrożność podczas korzystania z tego przeciążenia konstruktora SqlParameter do określenia wartości parametrów całkowitych. Ponieważ to przeciążenie przyjmuje wartość typu Object, musisz przekonwertować wartość integralną na typ Object, gdy wartość wynosi zero, jak pokazuje poniższy przykład C#. Kopiowanie

Parameter = new SqlParameter("@pname", Convert.ToInt32(0)); 

Jeśli nie wykonywać tej konwersji, kompilator zakłada, że ​​starają się wywołać SqlParameter (string, SqlDbType) przeciążenie konstruktora.

Sugeruję użyć coś podobnego

cmd.Parameters.Add(
    new SqlParameter("Field1", SqlDbType.Int32) { Value = field1Val }); 

zamiast jawnie ustawić typ.

+3

OP używa Oracle, a nie SQL Server, więc to byłby OracleParameter ... ale twoja odpowiedź nadal jest ważna. Jednak to nie wyjaśnia, dlaczego kiedyś pracował ... –

+0

D'oh, przepraszam. Nie pamiętałem, jak nazywa się wersję Oracle, więc chciałem użyć nazwy klasy podstawowej, DbParameter.To prawda, nie jestem pewien, dlaczego to mogło zmienić rzeczy, chyba że dopiero zaczynał przekazywać parametry zerowe. – Rup

+0

+1 To było dobre przypuszczenie, ale nie - przeszedłem przez rzeczywiste parametry w trybie debugowania i sprawdziłem wszystkie ich wartości, i wszystkie są poprawne. (Warto zauważyć, że wszystkie wartości są konwertowane na ciągi - wydaje się absurdalne przekonwertowanie liczby na ciąg znaków na kliencie, tak aby można było z powrotem ją przekonwertować po stronie serwera!) –

Powiązane problemy