The conversion of the varchar value '6000545901' overflowed an int column - sql-server-2008

Begin
UPDATE pmptxft
SET
vaccno = (SELECT max(cast(isnull(vaccno,0) AS int)) + 1 FROM pmptxft WHERE iPRACID=#IPRACID)
WHERE ipatId = #PatientIdentity
END
Here vaccno datatype is varchar(max). Any Help in this regard will be appreciated.

I assume a datatype error is the cause. When you compare two values of a different datatype an automatic datatype conversion can cause such an error.
Check the datatypes of
the ipracis column and the #IPRACID variable
the ipatId column and the #PatientIdentity variable

The value 6000545901 is out of the range. The int data type has a range of:
-2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647)
Try using BIGINT instead:
UPDATE pmptxft
SET vaccno = (SELECT Max(Cast(Isnull(vaccno, 0) AS BIGINT)) + 1
FROM pmptxft
WHERE ipracid = #IPRACID)
WHERE ipatid = #PatientIdentity
Here's a working example.

Related

MySQL, Concat int and save to veriable and use variable with 'IN' or 'NOT IN'

I want to CONCAT value in ID column in string variable and use the variable with IN in SQL as under:
SET #ActID = CONCAT(CAST(5 AS CHAR),',',CAST(15 AS CHAR));
SELECT * FROM `accounts` WHERE `ID` IN (#ActID);
It returns record having ID = 5 and ignore record having ID = 15.
#ActID is a comma separated list string literal and not a list of values.
So the list inside the parentheses of the IN operator contains only 1 value: '5,15'
when you compare 5 to '5,15' the result is TRUE
when you compare 15 to '5,15' the result is FALSE
because '5,15' is converted to the integer value 5 according to the rules described here.
What you want is the function FIND_IN_SET():
SET #ActID = CONCAT(CAST(5 AS CHAR),',',CAST(15 AS CHAR));
SELECT * FROM `accounts` WHERE FIND_IN_SET(`ID`,#ActID) > 0;
Change to ...= 0 for the equivalent of NOT IN.
See a simplified demo.
Note: SET #ActID = CONCAT(5,',',15); works fine.

Increment JSON field in Mysql Json column results in float not integer

For some reason unknown to me, the below code I use to increment a json field converts it to a float and not an integer
UPDATE tags SET tag_meta = JSON_SET(IFNULL(tag_meta,
JSON_OBJECT('insert_count', 1)), '$.insert_count',
IFNULL(tag_meta->>'$.insert_count', 0) + 1) WHERE tag_id = 123456789;
results in;
{"insert_count": 1.0}, {"insert_count": 2.0}... etc
and not
{"insert_count": 1}, {"insert_count": 2}
how to just keep it as integers?
Maybe it works. Try it if you want.
UPDATE table_name
SET column_name= JSON_INSERT(column_name, '$.name', 'Jhon')
WHERE id = 2
And look source link>>> https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html
You should care about NULL values and also casting types:
JSON_SET(COALESCE(`tag_meta`,'{}'), '$.fieldName',
IF(JSON_UNQUOTE(JSON_EXTRACT(tag_meta, '$.fieldName')) REGEXP ('^[0-9]+$'),
JSON_UNQUOTE(JSON_EXTRACT(tag_meta, '$.fieldName')), 0) + 1)

How to Auto Increment ID Numbers with Letters and Numbers

How to Auto Increment ID Numbers with Letters and Numbers, example "KP-0001" it will increment to "KP-0002"
Thank you!
here is a useful article
auto increment with a string of numbers and letters
But basically I encourage you to create your own algorithm on this. You can add that algorithm in BEFORE INSERT trigger. Or you can do that on the front-end.
Example of pseudocode for the algorthm
get the lastID [KP-0001]
remove some characters and put it in a variable [KP-]
convert the remaining into number since it's a string [0001]
increment by 1 [1 + 1 = 2]
convert it back to string and pad zero on the right [0002]
concatenate the variable and the newly incremented number [KP-0002]
save it.
I tried to do that in many ways but was unable to reach the solution... I also used triggers but that too didn't help me...
But I found a quick solution for that...
For example you want your employee to have employee codes 'emp101', 'emp102',...etc.
that too with an auto increment...
First of all create a table with three fields the first field containing the letters you want to have at the beginning i.e."emp", the second field containing the auto increasing numbers i.e 101,102,..etc., the third field containing both i.e 'emp101', 'emp102',...etc.
CREATE TABLE employee
(
empstr varchar( 5 ) default 'emp',
empno int( 5 ) AUTO_INCREMENT PRIMARY KEY ,
empcode varchar( 10 )
);
now providing an auto_increment value to empno.
ALTER TABLE employee AUTO_INCREMENT=101;
now coming to the topic... each time you insert values you have to concatenate the first two fields to get the values for the third field
INSERT INTO employee( empcode )
VALUES ('xyz');
UPDATE employee SET empcode = concat( empstr, empno ) ;
You can't auto increment varchar data type. Other way of doing this is to bifurcate varchar column into two different columns one will have integer part and other will have alphabet like in your case KP- once you auto increment all integer rows just concatenate these two columns
CREATE TABLE Customer (
CUSId INT NOT NULL IDENTITY(1, 1) PRIMARY KEY
,CUSKey AS 'Cus' + RIGHT('000' + CONVERT(VARCHAR(5), CUSId), 6) PERSISTED
,CusName VARCHAR(50)
,mobileno INT
,Gender VARCHAR(10)
)
Auto-increment is an integer, so adding text will not be possible.
Check out this question for other references.
Make a procedure, in my case MySQL.
CREATE PROCEDURE MOSTRAR_CODIGO_CLASE_PRODUCTO()
BEGIN
declare max varchar(10);
declare num int;
declare CCodigo varchar(10);
set max = (select MAX(Codigo_CP) from CLASE_PRODUCTO);
set num = (SELECT LTRIM(RIGHT(max,4)));
if num>=1 and num <=8 then
set num = num + 1;
set CCodigo = (select concat('CP000' , CAST(num as CHAR)));
elseif num>=9 and num <=98 then
set num = num + 1;
set CCodigo = (select concat('CP00' , CAST(num as CHAR)));
elseif num>=99 and num <=998 then
set num = num + 1;
set CCodigo = (select concat('CP0' , CAST(num as CHAR)));
elseif num>=999 and num <=9998 then
set num = num + 1;
set CCodigo = (select concat('CP' , CAST(num as CHAR)));
else
set CCodigo=(select 'CP0001');
end if;
SELECT MAX(CCodigo) AS Codigo_CP FROM CLASE_PRODUCTO;
END $
Java Class
public static boolean insertarClaseProducto(ClaseP cp){
boolean resp = false;
Connection cn;
Connection con = new Connection();
cn = con.connect();
try{
CallableStatement cs = cn.prepareCall("CALL REGISTRAR_CLASE_PRODUCTO (?)");
cs.setString(1, cp.getNombreCP());
int i = cs.executeUpdate();
if(i==1)
resp = true;
else
resp = false;
}catch(Exception e){System.out.println(e);}
return resp;
}
returns:
Codigo_MP Nombre_MP Estado_MP
MP0001 LG HAB
MP0002 GENIUS HAB
MP0003 MICRONICS HAB
MP0004 SONY HAB
MP0005 PANASONIC HAB

How to find the first number in a text field using a MySQL query?

I like to return only the first number of a text stored in a column of a database table.
User have put in page ranges into a field like 'p.2-5' or 'page 2 to 5' or '2 - 5'.
I am interested in the '2' here.
I tried to
SELECT SUBSTR(the_field, LOCATE('2', the_field, 1)) AS 'the_number'
FROM the_table
and it works. But how to get ANY number?
I tried
SELECT SUBSTR(the_field, LOCATE(REGEXP '[0-9], the_field, 1)) AS 'the_number'
FROM the_table
but this time I get an error.
Any ideas?
Just use REGEXP_SUBSTR():
SELECT REGEXP_SUBSTR(`the_field`,'^[0-9]+') AS `the_number` FROM `the_table`;
Notes:
I'm using MySQL Server v8.0.
This pattern assumes that the_field is trimmed. Otherwise, use TRIM() first.
REGEXP is not a function in MySQL, but something of an operator. Returns 1 if field matches the regular expression, or 0 if it does not. You cannot use it to figure out a position in a string.
Usage:
mysql> SELECT 'Monty!' REGEXP '.*';
-> 1
As for answer to the question: I don't think there is a simple way to do that using MySQL only. You would be better off processing that field in the code, or extract values before inserting.
For the specific case in the question. Where the String is {number}{string}{number}
there is a simple solution to get the first number. In our case we had numbers like 1/2,3
4-10
1,2
and we were looking for the first number in each row.
It turned out that for this case one can use convert function to convert it into number. MySQL will return the first number
select convert(the_field ,SIGNED) as the_first_number from the_table
or more hard core will be
SELECT
the_field,
#num := CONVERT(the_field, SIGNED) AS cast_num,
SUBSTRING(the_field, 1, LOCATE(#num, the_field) + LENGTH(#num) - 1) AS num_part,
SUBSTRING(the_field, LOCATE(#num, the_field) + LENGTH(#num)) AS txt_part
FROM the_table;
This was original post at source by Eamon Daly
What does it do?
#num := CONVERT(the_field, SIGNED) AS cast_num # try to convert it into a number
SUBSTRING(the_field, 1, LOCATE(#num, the_field) + LENGTH(#num) - 1) # gets the number by using the length and the location of #num in field
SUBSTRING(the_field, LOCATE(#num, the_field) + LENGTH(#num)) # finds the rest of the string after the number.
Some thoughts for future use
Its worth keeping another column which will hold the first number after you parsed it before insert it to the database. Actually this is what we are doing these days.
Edit
Just saw that you have text like p.2-5 and etc.. which means the above cannot work as if the string does not start with a number convert return zero
There's no built-in way that I know of, but here's a Mysql function you can define, this will do it (I didn't code for minus-signs or non-integers, but those could of course be added).
Once created, you can use it like any other function:
SELECT firstNumber(the_field) from the_table;
Here's the code:
DELIMITER //
CREATE FUNCTION firstNumber(s TEXT)
RETURNS INTEGER
COMMENT 'Returns the first integer found in a string'
DETERMINISTIC
BEGIN
DECLARE token TEXT DEFAULT '';
DECLARE len INTEGER DEFAULT 0;
DECLARE ind INTEGER DEFAULT 0;
DECLARE thisChar CHAR(1) DEFAULT ' ';
SET len = CHAR_LENGTH(s);
SET ind = 1;
WHILE ind <= len DO
SET thisChar = SUBSTRING(s, ind, 1);
IF (ORD(thisChar) >= 48 AND ORD(thisChar) <= 57) THEN
SET token = CONCAT(token, thisChar);
ELSEIF token <> '' THEN
SET ind = len + 1;
END IF;
SET ind = ind + 1;
END WHILE;
IF token = '' THEN
RETURN 0;
END IF;
RETURN token;
END //
DELIMITER ;

SQL: Auto Increment value during insert

I have the an existing table that for some reason the designer decided to manually control the Primary Key value by storing the last used value in a seperate table (changing the table to use Identity is not an option right now).
I now need to do a mass update to this table as follows:
DECLARE #NeedFieldID int
SET #NeedFieldID = 62034
INSERT INTO T_L_NeedField (NeedID, NeedFieldID, FieldName, Sequence, DisplayAs, FieldPrompt, DataType, ValidOptions, IsRequiredForSale)
(
SELECT
DISTINCT n.NeedID,
#NeedFieldID + 1,
'DetailedOutcome',
999,
'Detailed Outcome',
'Select appropriate reason for a No Sale outcome',
'T',
'Pricing, Appointment Date / Time Not Available, Will Call Back, Declined',
0
FROM T_L_Need n
INNER JOIN T_L_NeedField nf
ON n.NeedID = nf.NeedID
WHERE (n.Need LIKE 'Schedule%' AND n.Disabled = 0)
)
Obviously '#NeedFieldID + 1' doesn't work (just using it to show what I want to do). How can I increment #NeedFieldID as SQL inserts the values for each of the distinct NeedId's? I am using SQL Server 2008.
You want row_number():
DECLARE #NeedFieldID int
SET #NeedFieldID = 62034
INSERT INTO T_L_NeedField (NeedID, NeedFieldID, FieldName, Sequence, DisplayAs, FieldPrompt, DataType, ValidOptions, IsRequiredForSale)
(
SELECT
DISTINCT n.NeedID,
#NeedFieldID + row_number() over (order by n.NeedID),
'DetailedOutcome',
999,
'Detailed Outcome',
'Select appropriate reason for a No Sale outcome',
'T',
'Pricing, Appointment Date / Time Not Available, Will Call Back, Declined',
0
FROM T_L_Need n
INNER JOIN T_L_NeedField nf
ON n.NeedID = nf.NeedID
WHERE (n.Need LIKE 'Schedule%' AND n.Disabled = 0)
)
However, your best bet is to make NeedFieldID an identity column and just let SQL Server do the work for you.