Operator does not exist: text + integer [Postgres 9.5] - postgresql-9.5

i have an issue with this piece of code coming from SQL :
UPDATE resultats_du_jour
SET Heure_debut = CONCAT(SUBSTRING(Heure_debut,1,2) +
12,SUBSTRING(Heure_debut,3,3))
WHERE Heure_debut LIKE '%PM';
This gives me the following output :
sql:53: ER ROR: operator does not exist: text + integer LINE 1: ...ET Heure_debut = CONCAT(SUBSTRING(Heure_debut,1,2)+12,SUBSTR...
I understand that you cannot add text+integer, but how can i proceed to do that?
Many thanks.

If you want to add 12 to the numerical equivalent of the first substring you take, and then concatenate it again back to text, then you may use casts:
UPDATE resultats_du_jour
SET Heure_debut = CONCAT((SUBSTRING(Heure_debut, 1, 2)::int + 12)::text,
SUBSTRING(Heure_debut, 3, 3))
WHERE Heure_debut LIKE '%PM';
This feels a bit hackish, and in general as a matter of good design you should decide whether a certain type of data is text or a number. Here, if you had things stored as numbers, you might not need to cast at all.

Related

Substring parsing within inconsistent text column

I have a text column that has a data value (int) within it that I need to parse out. The problem is that it is not in the same character column, so a simple substring(x, 180, 5) won't work as it sometimes will return a character as well.
The data value always comes after the phrase 'value received:'.
Is it possible to parse the value out whereby SQL will take the next 3 values after this wording? Or even better, can you "catch" the value between two words? As before the value is a : and after the value there is always the word "complete".
You can use something like this:
select substring(x, charindex('value received', x) + 14, 5)
Without sample data, this might be off by a character or two.

Error checking in T-SQL Script

I am self taught in T-SQL, so I am sure that I can gain efficiency in my code writing, so any pointers are welcomed, even if unrelated to this specific problem.
I am having a problem during a nightly routine I wrote. The database program that is creating the initial data is out of my control and is loosely written, so I have bad data that can blow up my script from time to time. I am looking for assistance in adding error checking into my script so I lose one record instead of the whole thing blowing up.
The code looks like this:
SELECT convert(bigint,(SUBSTRING(pin, 1, 2)+ SUBSTRING(pin, 3, 4)+ SUBSTRING(pin, 7, 5) + SUBSTRING(pin, 13, 3))) AS PARCEL, taxyear, subdivisn, township, propclass, paddress1, paddress2, pcity
INTO [ASSESS].[dbo].[vpams_temp]
FROM [ASSESS].[dbo].[Property]
WHERE parcelstat='F'
GO
The problem is in the first part of this where the concatenation occurs. I am attempting to convert this string (11-1111-11111.000) into this number (11111111111000). If they put their data in correctly, there is punctuation in exactly the correct spots and numbers in the right spots. If they make a mistake, then I end up with punctuation in the wrong spots and it creates a string that cannot be converted into a number.
How about simply replacing "-" and "." with "" before CONVERT to BIGINT?
To do that you would simply replace part of your code with
SELECT CONVERT(BIGINT,REPLACE(REPLACE(pin,"-",""), ".","")) AS PARCEL, ...
Hope it helps.
First, I would use replace() (twice). Second, I would use try_convert():
SELECT try_convert(bigint,
replace(replace(pin, '-', ''), '.', '')
) as PARCEL,
taxyear, subdivisn, township, propclass, paddress1, paddress2, pcity
INTO [ASSESS].[dbo].[vpams_temp]
FROM [ASSESS].[dbo].[Property]
WHERE parcelstat = 'F' ;
You might want to check if there are other characters in the value:
select pin
from [ASSESS].[dbo].[Property]
where pin like '%[^-0-9.]%';
Why not just:
select cast(replace(replace('11-1111-11111.000','-',''),'.','') as bigint)
simply, use the next code:-
declare #var varchar(100)
set #var = '11-1111-11111.000'
select convert(bigint, replace(replace(#var,'-',''),'.',''))
Result:-
11111111111000

SQL Check constraint on substrings

Forgive me, if this problem is solved in another ticket on SO... I've been searching, but can't seem to find quite the right solution...
I am creating a table. Column 'Creditor' is numeric all the way, EXCEPT that the very last char may be a dash.
This means that examples like '1234-', '92846293' and so on, are valid, and that '12354-53', '12345K' are invalid.
The string length is not fixed (except it's a varchar(50)).
I don't know how to create the check constraint.
Please help!
You did not state your DBMS. For PostgreSQL this would be:
alter table foo
add constraint check_creditor check (creditor ~ '^([0-9]+)\-?$');
For Oracle this would be:
alter table foo
add constraint check_creditor check (regexp_like(creditor, '^([0-9]+)\-?$'))
If your DBMS supports regular expressions, you will need to use the syntax for your DBMS to check this. The regular expression itself '^([0-9]+)\-$' will most probably be the same though.
Thank you for your replies.
The proposal on '%[^0-9]%' was a nice eye-opener for me, as I didn't know the ^ operator before.
I did two versions of the required constraint. One using "only" AND, OR, substrings and isnumeric. No fancy indices or exclusions. Was waaaay too long.
The other version consisted of AND, OR, substrings and insmuric, but with the inclusion of the proposed ^ operations. Looks a lot nicer.
Then, in the end, I went with a third solution :-)
Added a bool column on the DB, RequiresCreditorValidation, and implemented a Regex in my C# code.
For others hoping to benefit from the resulting checks, here they are.
Starting with the "ugly" one:
CHECK ((val NOT IN ('+','-') AND (ISNUMERIC(val) = 1) OR
(ISNUMERIC(SUBSTRING(val, 1, DATALENGTH(val) -1))) = 1) AND
((SUBSTRING(val, (DATALENGTH(val)),1) LIKE '[0-9]') OR
(SUBSTRING(val, DATALENGTH(val),1) = '-')) AND
(SUBSTRING(val, 1, 1) NOT IN ('+','-')) )
The second one:
CHECK ( (SUBSTRING(val, 1, DATALENGTH(val) - 1) NOT LIKE '%[^0-9]%') AND
(SUBSTRING(val, DATALENGTH(val),1) LIKE '%[0-9-]') AND (DATALENGTH(val) > 0)
AND SUBSTRING(val, 1,1) NOT IN ('+','-') )
And then the Regex:
var allButLast = kreditorId.Substring(0, kreditorId.Length - 1);
if (Regex.Match(allButLast, "[^0-9]").Success)
return false;
if (!kreditorId.EndsWith("-"))
if (Regex.Match(kreditorId, "[^0-9]").Success)
return false;
return true;
Thank you all for good, qualified and quick replies.
For SQL Server:
Test 1: all characters apart from the last are numeric (alternatively, there does not exist a character that is non-numeric):
CHECK ( SUBSTRING(Creditor, 1, LEN(Creditor) - 1) NOT LIKE '%[^0-9]%' )
Test 2: the last character is either numeric or a dash:
CHECK ( SUBSTRING(Creditor, LEN(Creditor), 1) LIKE '%[0-9-%]' )
The above assumes Creditor cannot be the empty string i.e.
CHECK ( LEN(Creditor) > 0 )
Just for fun:
CHECK ( REVERSE(CAST(REVERSE(Creditor) + REPLICATE(0, 50) AS CHAR(50)))
LIKE REPLICATE('[0-9]', 49) + '[0-9-]' )

how to rearrange a data

I have a table like this:-
Item Model
------------------------
A 10022009
B 10032006
C 05081997
I need to rearrange/convert the Model column into this format:-
Item Model
------------------------
A 20090210
B 20060310
C 19970805
The Model column is character.
Thanks
You can try the following
UPDATE MyTable
SET Model = substr(Model, 5, 4) + substr(Model, 3, 2) + substr(Model, 1, 2)
The right way to do this, assuming those are date fields (and they certainly look like them), is to put that data into a date type column, not a string type column.
Then you can use the DBMS-provided date/time manipulation functions as they were meant to be used, including being able to extract them in the format and order that you want.
Normally, I would have proposed a simple textual change with substrings but, since you're going to change the data anyway, the best thing to do is bite the bullet and change the schema so all your problems disappear (not just one of them).
If you want to keep it as a string type, the syntax to use depends on your DBMS. It's likely to be one of the following:
substring (column, start, length) # substr for Oracle, I think.
substring (column FROM start for length)

What's wrong with this VB.NET Substring call?

dim dataType as String
toolTip="Marks And Number[String]"
I want to get the [String] alone.
dataType = toolTipText.Substring(toolTipText.IndexOf("[") + 1, toolTipText.IndexOf("]") - 1)
it shows an error. Regarding the length of the string.
What's wrong with my code.I dont know ,
Some times I have these type of problems . Standing with simple loops or conditions .
The second parameter is length, not ending index. You need to subtract your starting index from it.
Not that it's great code but
dataType = toolTip.Substring(toolTip.IndexOf("[") + 1, toolTip.Length - toolTip.IndexOf("[") - 2)
would sort you out.
The second parameter is the length of the substring - not the end index.
Might be better to take a look at regex.