This error message can be caused by various things, and it’s isn’t always easy to determine the cause. The best method is to remove parts of the query one-by-one until you discover the problematic one. This error message is actually the same for different kind of errors. Here are the causes and explanations:
1. Division by zero
Take a look and see if you have any divisions in your equasions. Is it possible that some of the values can be zero? If this is the case, you can use the CASE statement to replace the zero with something else. Or you can use DZERO function from rFunc UDF library. Examples:
select 1/0 from rdb$database;
select dzero(1, 0, 0) from rdb$database;
Please note that DZERO would return zero even for NULL input. Depending on your requirements, it might be better to use CASE (which is available since Firebird 1.5). Here’s an example showing how to use CASE:
CREATE TABLE test ( x integer );
COMMIT;
INSERT INTO TEST (X) VALUES (NULL);
INSERT INTO TEST (X) VALUES (1);
INSERT INTO TEST (X) VALUES (0);
SELECT x, CASE when x = 0 then 0 else 10/x END
FROM test;
2. Arithmetic overflow
If you use fixed precision datatypes (smallint, integer, bigint, decimal and numeric), it is possible that the result of calculation doesn’t fit the datatype. Try casting the values in complex expressions as double precision and see whether the error goes away. If it works and you don’t care about being too precise, you can leave it at that. Otherwise you need to check every operation and calculate the result.
Here’s an example: if you multiply 9.12 with 8.11 (both numeric(18,2)) you would get 73.9632. If Firebird would store that into numeric(18,2) datatype, we would lose 0.0032. Doesn’t look much, but when you have complex calculations, you can easily loose thousands (dollars or euros). Therefore, the result is stored in numeric(18,4).
Problems are rarely seen with such low precision as 2. Let’s use some bigger precision. For example, numeric(18,6) times numeric(18,6) yields numeric(18,12) result, meaning that maximal value it can store is 9223372.036854775807. If (for example) you wish to keep only 6 digits of precision, you could use something like:
cast(value1 as numeric(18,3)) * cast(value2 as numeric(18,3))
which would yield numeric(18,6) result, but it is quite possible that you would get more accurate result by casting to double:
cast(cast(value1 as double precision) * cast(value2 as double precision) as numeric(18,6))
Also, if you have mixed multiplications and divisions it helps to change the order of operations, so that the overflow doesn’t happen.
3. String truncation
It happens when the concatenated string doesn’t fit the underlying CHAR or VARCHAR datatype size. If the result goes into a table column, perhaps it’s a valid error. Or maybe you really need to increase the column size. Similar goes for intermediary values stored in stored procedure or trigger variables.
4. Character transliteration failed
This happens when you have data in database stored in one character set, but the transliteration to required character set fails. There are various points where character set transliteration occurs. There is an automatic one:
Every piece of data you retrieve from database (via SELECT or otherwise) is transliterated from character set of database table’s column to connection character set. If character sets are too different, there will be two traslations: first from column charset to Unicode and then from Unicode to the connection charset.
Also, you can request transliteration manually by CASTing the column to another charset, example:
CAST(column_name AS varchar(100) character set WIN1251).
The reason that transliteration can fail is that simply some characters don’t exist in certain character sets. For example, WIN1252 doesn’t contain any Cyrillic characters, so if you use connection charset WIN1252 and try to SELECT from a column with Cyrillic characters, you may get such error.
In modern internationalized computer world, it is best to use Unicode or UTF8 in your applications and UTF8 connection character — if your connectivity library has provisions for it. And make sure you use at least Firebird 2.0, which has excellent UTF8 support.
5. Wrong order of parameters when using DotNetFirebird
The order in which Parameters are added to a FbCommand when using DotNetFirebird might cause the -303 exception with the hint «Arithmetic exception, numeric overflow, or string truncation». The order of the parameters has to fit the order of the params in the stored procedure — otherwise the exception will be thrown. Example (.NET, C#, DotNetFirebird (using FirebirdSql.Data.FirebirdClient;)):
FbCommand CMD = new FbCommand(«TBLTEXT_ADDTEXT», cnn);
CMD.Parameters.Add(«TEXT1», FbDbType.VarChar, 600).Value = strText1;
CMD.Parameters.Add(«TEXT2», FbDbType.VarChar, 600).Value = strText2;
CMD.CommandType = CommandType.StoredProcedure;
CMD.ExecuteNonQuery();
If the order of the parameters inside the procedure «TBLTEXT_ADDTEXT» differ from the order in which you�re adding parameters to the FbCommand-Object, you�ll receive the -303 error.
Note: Section 5 of this FAQ was contributed by Andre Bonin.
Исходя из этого, я прошу сделать хотя бы быстрогрязный хак, который для меня сэкономил бы, скажем, один час тупой и неприятной работы в неделю.
Раз уж ты имеешь отношение к разработке, то как ты оцениваешь возможность вывода нормального сообщения для данной ошибки?
Неприятная ошибка arithmetic exception, numeric overflow, or string truncation. Когда она возникает в ходе insert или update, меняющем много полей, нелегко бывает найти конкретную причину.
Тяжко это. навешивать на него (исключение) дополнительную информацию, такую как имя переменной, позицию в строке запроса и т.п.
Если эта ошибка столь часто возникает, то может есть смысл:а) ввести более тщательную проверку входных аргументов ? б) сделать «побольше ширину» у полей, раз уж данные стали столь «гиговыми» ?
> Автор: afgm> В детали реализации не вникал, но для меня загадка почему не выводится номер строки,Вы забыли, что текст XP компилируется в BLR и выполняется именно BLR, а не красиво отформатированный запрос. И номер строки BLR вызвайвей ошибку совсем не обязательно может совпадать с номером строки в XP.
выполняется именно BLR, а не красиво отформатированный запрос. И номер строки BLR, вызвавшей ошибку, совсем не обязательно может совпадать с номером строки в XP.
и выполняется именно BLR, а не красиво отформатированный запрос
Даже ещё хуже: BLR компилируется в дерево выполнения, которое потом проходит две стадии оптимизации. Но надо ждать Влада, это он делал вывод стэка для PSQL, он точно скажет почему это не работает для SQL.
Во-вторых, если проверять все аргументы (они не обязательно входные, но могут получаться и в результате конкатенации строк, например, при динамической генерации запроса), то объём кода хр.пр. вырастет раза в полтора, и главное, сильно упадёт читаемость.
Я даже могу предположить, что оно может никогда не заработать как раз из-за необходимости оптимизировать. Вполне ясно общее правило: программа, пригодная для отладки, работает медленнее программы, оптимизированной по скорости. Поэтому, выдача подробной информации о строках не может быть задаром.
Данные, кстати, необязательно выводить в firebird.log. Я предложил firebird.log потому, что данные, вызвавшие ошибку, могут быть конфиденциальны и содержать нечто, чего нельзя видеть пользователю.
убеждает FB dev team в суперважности этой фичи и FB dev team её реализует
I use firebird as my database and mybatis to manipulate the data, but when I run a query with a keyword whose length is greater than 5, then the following errors happen:
If it’s length is lesser than 6, it runs fine. I update mybatis and firebird to latest version, and the result is the same thing.
Detailed sql is as below:
Followed by the error log:
And mybatis sql defination:
I did more test and discovered that title like is ok no matter how long the keyword,content like cause the error when the length is bigger than 5. title column is varchar(100),content is Blob sub_type 1 , but anyway it’s totally fine in sql console which makes me so confused, error just happens when running in java