![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: IBExpert
Incompatilbe column/host variable data type
Guten Morgen,
ich bekomme bei folgendem Statement
SQL-Code:
den Fehler
select
lt.id, lt.date_time, lt.operation from ibe$log_tables lt where ( (:tmp_tabellen_name = '*') or ((not (:tmp_tabellen_name = '*')) and (lt.table_name = f_lrtrim8(f_upper(:tmp_tabellen_name)))) ) and ( (:tmp_db_operation = '*') or ((not (:tmp_db_operation = '')) and (lt.operation = f_lrtrim8(f_upper(:tmp_db_operation)))) ) order by lt.date_time desc rows 1
Code:
als Parameter belege ich
Incompatilbe column/host variable data type.
Dynamic SQL Error. SQL error code = -303 arithmetic exception, numeric overflow or string truncation. string right truncation. tmp_tabellen_name = '*' tmp_db_operation = '*' Beide Parameter werden laut IBExpert mit CHAR(8191) übergeben. Die Funktionsbibliothekt "FreeAdhocUDF" kennt die Funktionen f_lrtrim8 mit dem Argument CSTRING(8191) und f_upper mit dem Argument CSTRING(8191) Was mache ich falsch? |
AW: Incompatilbe column/host variable data type
AFAIK kann man keine Tabellen-/View-/Prozedurnamen parametrisieren, sondern lediglich Werte.
|
AW: Incompatilbe column/host variable data type
Ich glaub entscheidend in DeddyHs Liste fehlt für diesen Fall auch noch Feld/Spalten-Namen, die man nicht parametrisieren kann.
|
AW: Incompatilbe column/host variable data type
sorry - ich verstehe nicht.
ich vergleiche Werte einer Tabelle mit einem Parameter
Code:
lt.table_name = f_lrtrim8(f_upper(:tmp_tabellen_name)))
|
AW: Incompatilbe column/host variable data type
Zitat:
|
AW: Incompatilbe column/host variable data type
z.B.:
SQL-Code:
where
( (:tmp_tabellen_name = '*') |
AW: Incompatilbe column/host variable data type
mhm - das geht aber:
Code:
select
cast(:parameter as integer) from rdb$database |
AW: Incompatilbe column/host variable data type
Das ist ja auch ein Wert.
|
AW: Incompatilbe column/host variable data type
das geht auch:
Code:
irgendwie verstehe ich es nicht..
select
cast(:parameter as integer) from rdb$database where :parameter = 1 |
AW: Incompatilbe column/host variable data type
Auch das ist eine Spaltenname und kein Tabellenname.
Man kann keine Tabellennamen parametrisieren. |
AW: Incompatilbe column/host variable data type
wenn ich die Abfrage im IBExpertstarte, wird sie vorbereitet
Code:
dann gebe ich den Parameter-Wert ein:
Plan:
PLAN (RDB$DATABASE NATURAL) ------ Performance info ------ Prepare time = 0ms Execute time = 0ms Avg fetch time = 0,00 ms Current memory = 74.771.328 Max memory = 146.467.576 Memory buffers = 2.048 Reads from disk to cache = 0 Writes from cache to disk = 0 Fetches from cache = 8
Code:
und führe die Anfrage aus. Als Resultat erhalte ich eine Zeile mit
Parameter INTEGER Wert = 1
Code:
Wenn das nicht geht, warum bekomme ich dann ein Ergebnis?
CAST
1 |
AW: Incompatilbe column/host variable data type
Noch ein Nachsatz:
ich kann nicht erkennen, wo ich hier einen Tabellenname parametrisiere. In unserer Applikation gibt es einige Statements, die ähnlich aufgebaut sind und funktionieren. Vielleicht nur aus Zufall - aber ich würde wirklich gerne verstehen, was ich da falsch mache. |
AW: Incompatilbe column/host variable data type
SQL-Code:
Die Frage ist ja, was man da als :Parameter eingibt: Wenn das die Zahl 1 ist steht da:
select
cast(:parameter as integer) from rdb$database where :parameter = 1
SQL-Code:
Herzlichen Glückwünsch.
select
cast(1 as integer) from rdb$database where 1 = 1 Das ist aber immer noch kein Feldname. Gib mal als Parameter an: RDB$RELATION_ID und schau was passiert. |
AW: Incompatilbe column/host variable data type
letzten Beitrag gelesen - weitergemacht:
weitere Tests haben ergeben, dass das Problem entsteht, wenn der Wert ein char bzw. varchar ist. Wird in der where-Klausel der Vergleichswert per
Code:
übergeben, klappt es.
cast()
Also das
Code:
Liefert als Ergebnis
select
'Test' from rdb$database where :parameter = cast('*' as varchar(8191)) 'Test' Während das
Code:
Bei einem Parameterwert mit Länge größer 1 (z.B. 'axf') den Fehler
select
'Test' from rdb$database where :parameter = '*'
Code:
liefert. Offenbar wird der Datentyp des Parameters anhand der Bedingung in der where-Klausel definiert.
Incompatilbe column/host variable data type.
Dynamic SQL Error. SQL error code = -303 arithmetic exception, numeric overflow or string truncation. string right truncation. |
AW: Incompatilbe column/host variable data type
OK. So langsam dämmert es mir, worauf die hinaus willst.
Hast du als Paramter '*' sollen z.B. alle Tabellen angezeigt werden, hast du dagegen als Parameter einen konkreten Tabellennamen, soll nur diese angezeigt werden? Bringt es was, die Bedingung umzudrehen: '*' = :parameter oder liegt es speziell am * dann mal probeweise ein anderes Dummy-Zeichen nehmen? Edit: Alternativ könnte man natürlich im Programm-Code diese unterscheidung treffen... |
AW: Incompatilbe column/host variable data type
@Jumpy
genau das ist die Intention. Ich verwende eine Stored procedure, da werden Parameter übergeben. Werden diese mit NULL übergeben, so wird in eine Variable ein '*' eingetragen, ansonsten schreibe ich den übergebenen Wert in die Variable. Die Variablen werden in einer Abfrage in der Stored Procedure verwendet - die Beispiele oben waren für den Thread hier stark vereinfacht. Wie geschildert: das geht mit numerischen Datentypen im Parameter (z.B. Integer), bei Char-Datentypen muss offenbar in der where Klausel mindestens der Vergleichs-String gecastet werden, damit es funktioniert. |
AW: Incompatilbe column/host variable data type
Nachtrag:
der Vorschlag, die Bedingung umzudrehen führt leider auch zum Fehler, das also funktioniert nicht:
Code:
select
'Test' from rdb$database where '*' = :parameter |
AW: Incompatilbe column/host variable data type
Nehmen wir nochmal dashier:
SQL-Code:
wenn nun Parameter asdf ist, dann wird daraus
select
'Test' from rdb$database where :parameter = '*'
SQL-Code:
Das ist kein gültiges SQL-Statement.
select
'Test' from rdb$database where asdf = '*' Bei der Angabe einer Zeichenfolge müssen um den Parameter ''. Da rdb$database nur einen Datensatz enthält, kommt als Ergebnis immer eine Zeile heraus, sofern die Where-Bedingung 1. ein gültiges Statement ergibt und 2. das Abfrageergebnis wahr ist. Machst Du sowas für eine Tabelle mit 10 Mio. Datensätzen, so kommen als Ergebnis bei einer wahren Wehrebedingung 10 Mio. Datensätze heraus. Der Inhalt der Wherebedingung ist dabei für den Tabelleninhalt absolut irrelevant. Du solltest bitte erstmal verbal beschreiben, was Du genau möchtest, dann kann man nach 'ner Lösung suchen. So erscheint mir das erstmal (überspitzt formuliert) absolut sinnfrei. Mit den Wherebedingungen
SQL-Code:
könntest Du die gleichen Ergebnisse erhalten.
where 1 = 1
-- bzw. where 1 = 2 Bei der Nutzung von Zeichenfolgen ginge auch
SQL-Code:
Als Ergebnis gibt es immer alle Sätze der Tabelle oder keinen Satz.
where 'asdf' = 'asdf'
-- bzw. where 'asdf' = '*' Sollte anstelle von asdf hier jedoch der Spaltenname gewünscht sein? Das geht nicht. Spaltennamen kann man nicht per Parameter übergeben, sondern nur Werte. dashier geht:
SQL-Code:
where Spaltenname = :Parameter
dashier geht nicht:
SQL-Code:
where :Spaltenname = 'Wert'
dashier geht auch nicht:
SQL-Code:
where :Spaltenname = :ParameterFuerDenWert
|
AW: Incompatilbe column/host variable data type
@nahpets
Zur einfacheren Diskussion ein konretes Beispiel. Ich verwende
Code:
Und das funktioniert wie gewünscht.
select
lt.id, lt.date_time, lt.operation, lt.user_name from ibe$log_tables lt where ( (:tmp_tabellen_name = cast('*' as varchar(201))) or ((not (:tabellen_name = cast('*' as varchar(201)))) and (lt.table_name = f_lrtrim8(f_upper(:tmp_tabellen_name)))) ) and ( (:tmp_db_operation = cast('*' as varchar(1))) or ((not (:tmp_db_operation = cast('*' as varchar(1)))) and (lt.operation = f_lrtrim8(f_upper(:tmp_db_operation)))) ) order by lt.date_time desc rows 1 |
AW: Incompatilbe column/host variable data type
Hallo,
laut dem hier ist es 8190, nicht 8191 ![]() Funktioniert es denn jetzt mit * oder mit einem Tabellen-Namen. |
AW: Incompatilbe column/host variable data type
inzwischen kam der rote Kasten. Aber trotzdem zur Erläuterung..
Das Problem mit den Parameter habe ich auch schon gehabt. Firebird versucht der Parameter :tmp_tabellen_name zu interpretieren. Es kommt zu dem Schluss ein '*' die Länge von 1 Zeichen hat. Für der Parameter :tmp_tabellen_name wird also der entsprechende Platz bereitgestellt. Wenn jetzt mit f_lrtrim8(f_upper(:tmp_tabellen_name)) ein String mit der Länge > 1 an den Parameter übergeben wird, gibt es ein "string right truncation". Man muss also Firebird mit cast() oder einer anderen Formulierung der Bedingung überreden entsprechen Platz zu Verfügung zu stellen. ich nehme mal ein einfacheres Beispiel. Es sollen nur die passenden oder alle Personen zurückgegeben werden. Für alle übergibt man * oder *** oder NULL je nach Variante
SQL-Code:
select
P.* from PERSON P where -- :NACHNAME = '' OR (P.NACHNAME = :NACHNAME) -- geht nicht :NACHNAME = '*' OR (P.NACHNAME = :NACHNAME) -- geht mit max 1 Zeichen -- :NACHNAME = '***' OR (P.NACHNAME = :NACHNAME) -- geht bis max 3 Zeichen -- (:NACHNAME = cast('*' as VARCHAR(10))) OR (P.NACHNAME = :NACHNAME) -- geht bis 10 Zeichen -- (cast(:NACHNAME as type of COLUMN PERSON.NACHNAME) = '*') OR (P.NACHNAME = :NACHNAME) -- geht bis Länge PERSON.NACHNAME -- (:NACHNAME = cast('*' as type of COLUMN PERSON.NACHNAME)) OR (P.NACHNAME = :NACHNAME) -- geht bis Länge PERSON.NACHNAME -- (:NACHNAME is null) or (P.NACHNAME = :NACHNAME) -- geht auch ohne cast() |
AW: Incompatilbe column/host variable data type
Ich hätte da noch einen Vorschlag aus der hinteren Ecke
SQL-Code:
select
lt.id, lt.date_time, lt.operation, lt.user_name from ibe$log_tables lt where lt.Tabellenname like '%'||:tablename||'%' Zitat:
Gruß K-H |
AW: Incompatilbe column/host variable data type
@hoika
ich habe die 8191 aus Anzeige im Eingabedialog für Parameter von IBExpert. War es nicht so, dass für ein varchar immer noch ein Zeichen hinzu kommt - also 8190 Zeichen für die Funktion aber der varchar hat 8191 Länge .. da muss ich selbst nochmals suchen. @p80286 probiere ich später nochmals @alex517 das muss es sein! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz