postgresql 12 function strange value / length behaviour - sqldatatypes

I have a char(13) column named a in table test.
I created a classic before insert function with the following line :
raise notice 'a: -->%<-- len = %', new.a, length(new.a);
When I run insert into test (a) values('1');, I get the following output :
a: -->1 <-- len = 1
Strange, no ?

No, not strange at all. char is a blank padded data type. So if you assign '1' to your column, it is actually stored as '1 '.
The solution is simple: don't use char(n)

Related

Difference between ORA-12899 and ORA-01480

I would like to understand the difference between ORA-12899 and ORA-01480
ORA-12899: value too large for column
ORA-01480: trailing null missing from STR bind value
Based on my understanding, I know about ORA-12899 and how it can come. Lets say if datatype for some column is VARCHAR2(100 BYTE) and I am trying to insert more than 100 BYTE in the column then I am getting ORA-12899.
What about ORA-01480 ? I searchthe ed on internet and and the similar explanation like ORA-12899
From google :
ORA-01480: trailing null missing from STR bind value
Cause: A bind variable of type 5 (null-terminated string) does not contain the terminating null in its buffer.
Maybe you're trying to insert a string in a column that is bigger than the column length. So, the terminating character is not being
inserted at the end of the string.
Both ORA-12899 and ORA-01480 look similar. Can someone please explain the exact difference with an example?
The error:
ORA-01480: trailing null missing from STR bind value
Is for languages such as C or C++ (among many others) which allow low level manipulation of string-like objects.
If you have a VARCHAR2(100) column and you try to pass, to a bind variable, the byte array:
['h','e','l','l','o']
Then you may get the ORA-01480 error because a NUL terminated string is expected and it should have been:
['h','e','l','l','o','\0']
And the NUL character is expected as it allows the SQL engine to determine the length of the VARCHAR2 variable length string.
An example is using Pro*C:
char s[2] = "ab";
EXEC SQL SELECT :s into :s2 FROM dual;
Outputs: ORA-01480: trailing null missing from STR bind value
char s[3] = "ab\0";
EXEC SQL SELECT :s into :s2 FROM dual;
Works.

SQL - MariaDB : SQL Error 1292 Truncated incorrect DOUBLE value

after few search with my buddy G, I found a lot of solution, but no one corresponds to my situation.
Quick explanation :
I am currently trying to create a "test table" which will receive 4 millions lines per day. That's around 48 lines/seconds.
To simulate this situation, I want to create a default number for my "LotNumber" column, which will being create based on hour and minutes.
Exemple : all the lines created at 9AM and 45min will have the following "LotNumber" : W11409:451
a.k.a W114+HH:MM+1
So, my default column value is :
concat(cast('W114' as char charset utf8mb4) + left(cast(curtime() as char charset utf8mb4),5) + cast('1' as char charset utf8mb4))
And hell yes, that's barbaric.
My "LotNumber" column is VARCHAR,
When I create a single line, HeidiSQL send error message 1292.
I am new to SQL, and I have no idea where my error is.
Your code works, just separate the data elements by , instead of +
select concat(
cast('W114' as char charset utf8mb4),
left(cast(curtime() as char charset utf8mb4),5),
cast('1' as char charset utf8mb4)
)
You can test on this db<>fiddle

How to remove/replace hyphens in postgresql

I have this set of data that contains hyphens sign in my cell. My plan is to replace this hyphens sign to a number of 0 so that I can convert my column to numeric data type to do a calculation. The tricky part is where I only need to replace the cell that only contains hyphens sign (row 2 and row 3) without changing the negative value (row 6,7,8 and 9). I tried to use
regexp_replace("M1KW",'-','0','g')
function but it does change the negative value as well.
Any other special command that I can use ?
This is my sample data:
You seem to want to treat the string '-' as '0'. If so, you can directly replace the values:
update t
set mikw = '0'
where mikw = '-';
so that I can convert my column to numeric data type to do a calculation
You don't need to UPDATE all rows before being able to convert the data type to the correct one:
alter table the_table
alter mikw type numeric
using (case when mikw = '-' then 0 else mikw::numeric end);
That will do the "update" and the change of the data type in a single operation, rather than two.
Seems like the RIGHT function would be useful here, for isolating only instances where the hyphen is the last character.
Try this out:
UPDATE your_table
SET M1KW = 0
WHERE RIGHT(M1KW, 1) = '-';

STUFF function sql returns null?

I have a specific column in a table, it shall contains only numbers in Nvarchar that have a length of 3. Unfortunately, some users wrote '12' but they should have written '012'. There were not enough validation at the time.
I need to fix that. Here is the logic I used :
UPDATE [Mandats_Approvisionnement].[dbo].[ARTICLE_ECOLE]
SET [UNIT_ADM] = STUFF(UNIT_ADM, 0, 0, '0')
WHERE LEN(UNIT_ADM) = 2;
The error goes like :
Cannot insert the value NULL into column 'UNIT_ADM', table
'Mandats_Approvisionnement.dbo.ARTICLE_ECOLE'; column does not allow
nulls. UPDATE fails.
I can't see where the problem is, I verified and all the records contain at least 2 characters, so the STUFF function cannot returns null as there are no NULL records in that table column [unit_adm]... How do I make it work ?
It should be stuff(UNIT_ADM,1,0,'0') as stuff returns null if the start position is 0.
Citing the documentation:
If the start position or the length is negative, or if the starting
position is larger than length of the first string, a null string is
returned. If the start position is 0, a null value is returned.
You could make this simpler by using
right('0' + UNIT_ADM, 3)
instead of stuff.

Can't compare 2 strings - strange errors

I have this code in my procedure:
IF old_value_l = new_value_l THEN
dummy_val_l := 0;
ELSIF old_value_l != new_value_l THEN -- This is line 4019 mentioned in the error
-- some code here
END IF;
But it is throwing some strange errors:
ORA-01722: invalid number
ORA-06512: at "DBS.MONITORING", line 4019
ORA-06512: at line 12
It clearly says that the number is invalid, but wait a minute, what number?
Both old_value_l and new_value_l are declared as VARCHAR2(255 CHAR)
and here is how:
new_value_l history.new_value%TYPE;
old_value_l history.old_value%TYPE;
Why even when both of the variables are declared as VARCHAR2 it says that the number is invalid?
I know that I'm missing an extremely small part here, but I can't spot it or understand my mistake at this momment.
EDIT
Values I'm comparing:
new_value_l = 15 and old_value_l = 10
Code like this does not tell us they are numbers, it tells that first variable has a type like column new_value in history table, and the second variable has a type like old_value in history table.
new_value_l history.new_value%TYPE;
old_value_l history.old_value%TYPE;
So, you need to:
Ensure that both of these columns have the same datatype, VARCHAR2
Sometimes errors appear in a line, while actual error is in next or previous line, so you have to check them too
Try to check there is no spaces stored in values by using trim
...
ELSIF trim(old_value_l) != trim(new_value_l)
...
I think you have to handle null values too.
...
ELSIF trim(old_value_l) != trim(new_value_l)
...
It will be converted to a number automatically. So, you can test it as per the below:
select 1 from dual where '114' >120;
select 1 from dual where '125' >120;
You'd better check whether each value has some characters which cannot be converted to a number, such as CRLF.