USE case statement on mixed value in SQL Server - sql-server-2008

How can I use a case statement that does something like
CASE
WHEN val IS STRING
THEN something
WHEN val > 0
THEN something
without throwing a conversion error? The column I'm dealing with is varchar, but it will either contain 'NO VALUE' or a number.

How about this...does this help
DECLARE #VAL VARCHAR(8)
SELECT #VAL = COLUMNNAME1 FROM TABLENAME1 WHERE SOMEOTHERCOL2 = SOMEVALUE;
SELECT
CASE
WHEN #VAL = 'NO VALUE' THEN NULL
WHEN CAST(#VAL AS BIGINT) > 0 THEN #VAL
ELSE 'LT 1'
END
FROM TABLE
WHERE COLUMNNAME1 = SOMEVALUE

By CASE'ing first and CAST'ing second, you will filter out the values that are causing the exception. Keep in mind this will still fail if some of the strings are anything other than 'NO VALUE'
SELECT CASE(so.val)
WHEN 'NO VALUE'
THEN null
ELSE CAST(so.val AS int)
END from dbo.SO41270497 so

Try:
DECLARE #myTable TABLE (Val varchar(10))
INSERT INTO #myTable VALUES ('No Value'),('1'),('2'),('3'),('4'),('5')
SELECT * FROM #myTable
SELECT CASE WHEN ISNUMERIC(Val) = 1 THEN CONVERT(int,Val) ELSE NULL END
AS Val FROM #myTable

Related

Error Code: 1241. Operand should contain 1 column(s) don't know how to fix this

DELIMITER //
CREATE PROCEDURE positioner(objectivedate date)
BEGIN
DECLARE var1 INT(3) DEFAULT 0;
DECLARE var2 INT(3) DEFAULT 0;
DECLARE var3 INT(3) DEFAULT 0;
SET var1 = (SELECT COUNT(CID) FROM erd.caddy WHERE (WorkDate = objectivedate, WorkTime = '1'));
SET var2 = (SELECT COUNT(CID) FROM erd.caddy WHERE (WorkDate = 'objectivedate', WorkTime = '2'));
SET var3 = (SELECT COUNT(CID) FROM erd.caddy WHERE (WorkDate = 'objectivedate', WorkTime = '3'));
SELECT var1 AS '1부',var2 AS '2부', var3 AS '3부';
END; //
DELIMITER ;
Hello I am trying to make a delimiter that counts number of CID by WorkTime (which means work session consists of 1,2,3) by putting certain WorkDate (which I set as objectivedate).
When I put CALL("2020-05-11")
The error says that:
Error Code: 1241. Operand should contain 1 column(s) 0.000 sec
I am certain that it's about SET var1 ... row, but I don't know how to fix this. I am desperate!!!
You have a syntax error in your where clause of all 3 queries
write like below:
var1= SELECT COUNT(CID) FROM erd.caddy WHERE WorkDate=objectiveDate and WorkTime='1'
You need to use boolean expressions for your conditions.
For example you have:
WHERE (WorkDate = objectivedate, WorkTime = '1')
But it should be :
WHERE (WorkDate = objectivedate AND WorkTime = '1')
Also I'm not sure you intended this:
WorkDate = 'objectivedate'
Putting 'objectivedate' in the single-quotes makes it a literal string 'objectivedate', not the variable objectivedate which is the date input parameter of the procedure.
Finally, I can suggest a simplification to your procedure:
CREATE PROCEDURE positioner(objectivedate date)
BEGIN
SELECT
COUNT(CASE WorkTime WHEN '1' THEN true END) AS '1부',
COUNT(CASE WorkTime WHEN '2' THEN true END) AS '2부',
COUNT(CASE WorkTime WHEN '3' THEN true END) AS '3부'
FROM erd.caddy
WHERE WorkDate = objectivedate;
END
This gets all three counts in one query, and you can skip declaring the local variables.

How can one determine if a field is numeric or a string in MySQL?

I've tried both CEIL and CAST methods suggested elsewhere. Neither of them work.
SELECT
CASE WHEN CEIL('foo') = 'foo' THEN 'Str' ELSE 'Num' END AS ceil_test_1,
CASE WHEN CEIL(123) = 123 THEN 'Str' ELSE 'Num' END AS ceil_test_2,
CASE WHEN CEIL('123') = 123 THEN 'Str' ELSE 'Num' END AS ceil_test_3,
CASE WHEN CAST('bar' AS UNSIGNED) = 'bar' THEN 'Str' ELSE 'Num' END AS cast_test_1,
CASE WHEN CAST(123 AS UNSIGNED) = 123 THEN 'Str' ELSE 'Num' END AS cast_test_2,
CASE WHEN CAST('123' AS UNSIGNED) = 123 THEN 'Str' ELSE 'Num' END AS cast_test_3
;
Expected Results are obvious: foo is a string. 123 is a number.
You can use REGEXP for that purpose.
SET #str := 'asdf', #str2 := '1d25';
is SpaceAndAlpha
SELECT
CASE
WHEN #str REGEXP '^[A-Z a-z]+$' THEN
'YES'
ELSE
'NO'
END AS isString; ---twisted from the definition of string;
is Nuemric
SELECT
CASE
WHEN #str2 REGEXP '^[0-9]+$' THEN ---or WHEN TRIM(#str2 REGEXP '^[0-9]+$'
'YES'
ELSE
'NO'
END AS isNumber;
Note: (In regex, ^ means begin, and $ means end)
EDIT:
Another interesting way to check is Numeric:
SET #str := ' 00000007166';
SELECT
CASE
WHEN CONCAT('',#str*1) = TRIM( LEADING '0' FROM TRIM(#str)) THEN
'YES'
ELSE
'NO'
END AS isNumber;
Note1.1:
First Trim function trims the leading and trailing spaces.
Second trim function takes into account the leading zeros (if any).
When you use a regular expression to solve a problem, you usually end up with two problems.
Use the information_schema views to determine the data type of a column.
create table test (
test_int integer not null
);
select data_type from information_schema.columns
where table_schema = 'sandbox'
and table_name = 'test'
and column_name = 'test_int';
data_type
--
int

Loop through a split string variable to insert rows in a stored procedure in SQL Server 2008

I am working on SQL Server 2008 to create a stored procedure that:
takes a string variable like this: '1,2,3'
splits the string using a table-valued function to get each value separately
and then inserts each value into a new row in a table
What I am trying to do is something like this:
WHILE (select vlaue FROM dbo.SplitString('1,2,3',',')) has rows
insert into TableName (col1,col2) values (col1Data, value)
I am having a hard time trying to find the right syntax for this.
I use this Table-valued function:
CREATE FUNCTION [dbo].[Split] (#sep char(1), #s varchar(512))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep, #s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(#sep, #s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
SUBSTRING(#s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
FROM Pieces
)
GO
Which takes a string with a separator and returns a table with two columns the first returns a 1-based position and the second the element at that position in the string:
Usage:
SELECT * FROM dbo.Split(',', '1,2,3')
Returns:
pn s
1 1
2 2
3 3
To Insert results into a table:
INSERT INTO TableName (Col1)
SELECT S FROM dbo.Split(',', '1,2,3)
For your specific example change your syntax to be:
insert into TableName (col1,col2)
select col1Data, value FROM dbo.SplitString('1,2,3',',')
The typical INSERT INTO ... SELECT ... should do:
INSERT INTO TableName (col1,col2)
SELECT #col1Data,value FROM dbo.SplitString('1,2,3',','))
If someone else is looking for this, I was about to make a split function as several answers mentioned but noticed there's a built-in function that does this already.
string_split was added in MSSQL 2016.
INSERT INTO Project.FormDropdownAnswers (FkTableId, CreatedBy, CreatedDate)
SELECT 123, TRY_CAST(value AS INT), #username, getdate()
FROM string_split('44,45,46,47,55',',')
https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
CREATE TABLE tablename
(
id SMALLINT ,
value INT
)
INSERT INTO tablename ( id, value )
SELECT * FROM dbo.Split('1,2,3',',')
try this....
If need to use as variables there is 2 nice options:
Procedure MF_SPLIT
CREATE PROC [MF_SPLIT] (#ELS NVARCHAR(MAX)=NULL OUTPUT, #RET NVARCHAR(MAX)=NULL OUTPUT, #PROC NVARCHAR(MAX)=NULL) AS BEGIN
IF #ELS IS NULL BEGIN
PRINT ' #ELS
List of elements in string (OUTPUT)
#RET
Next return (OUTPUT)
#PROC
NULL = '','', content to do split
Example:
DECLARE #NAMES VARCHAR(100) = ''ERICK,DE,VATHAIRE''
DECLARE #N VARCHAR(100)
WHILE #NAMES IS NOT NULL BEGIN
EXEC MF_SPLIT #NAMES OUTPUT, #N OUTPUT
SELECT List = #NAMES, ActiveWord = #N
END'
RETURN
END
SET #PROC = ISNULL(#PROC, ',')
IF CHARINDEX(#PROC, #ELS) = 0 BEGIN
SELECT #RET = #ELS, #ELS = NULL
RETURN
END
SELECT
#RET = LEFT(#ELS, CHARINDEX(#PROC, #ELS) - 1)
, #ELS = STUFF(#ELS, 1, LEN(#RET) + 1, '')
END
Usage:
DECLARE #NAMES VARCHAR(100) = '1,2,3'
DECLARE #N VARCHAR(100)
WHILE #NAMES IS NOT NULL BEGIN
EXEC MF_SPLIT #NAMES OUTPUT, #N OUTPUT
SELECT List = #NAMES, ActiveWord = #N
END
Procedure MF_SPLIT_DO (Depends of MF_SPLIT), less sintax to use BUT the code will be in a string and use default variable "#X"
CREATE PROC MF_SPLIT_DO (#ARR NVARCHAR(MAX), #DO NVARCHAR(MAX)) AS BEGIN
--Less sintax
DECLARE #X NVARCHAR(MAX)
WHILE #ARR IS NOT NULL BEGIN
EXEC MF_SPLIT #ARR OUT, #X OUT
EXEC SP_EXECUTESQL #DO, N'#X NVARCHAR(MAX)', #X
END
END
Usage:
EXEC MF_SPLIT_DO '1,2,3', 'SELECT #X'

Remove Non Numeric Values Within SQL Select Statement

I have a value in a database column VALUE:
C_4327
I need to strip the non numeric text from this so that it just leaves the numbers. I have tried using the REPLACE function within SQL but not I don't want to replace, just strip them out. I was previously using PHP to do this:
preg_replace("/[^0-9]/","",$row['VALUE']);
I'm retrieving the value in a SELECT statement.
Your help would be appreciated.
Thanks in advance
If you want to get the number at the end of the string, you can use the following arcane approach:
select reverse(reverse(value) + 0) as NumberAtEnd;
In your case:
value ='C_4327'
reverse(value) = '7234_C'
reverse(value) + 0 = 7234
reverse(reverse(value) + 0) = '4327'
you can create a Function like that/.
CREATE FUNCTION GetNumeric
(
#strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS BEGIN
DECLARE #intAlpha INT
SET #intAlpha = PATINDEX('%[^0-9]%', #strAlphaNumeric)
BEGIN
WHILE
#intAlpha > 0
BEGIN
SET #strAlphaNumeric = STUFF(#strAlphaNumeric, #intAlpha, 1, '' )
SET #intAlpha = PATINDEX('%[^0-9]%', #strAlphaNumeric )
END
END
RETURN ISNULL(#strAlphaNumeric,0)
END
GO
then call the function as follows
SELECT GetNumeric('123456789blahblahblah') AS filedname FROM your_table
you will get the answer : 123456789
simple way: how about substring...
select substr( value, 3 ) from mytable;
it works on your example - but not sure if your real data is more complicated.

Trim, convert and compare a string from an SQL DB, in a single SQL Query

I would like to retrieve data from a database which is of type varchar e.g
size: 100mm,100 ,20mm, 500, 450mm and trim 'mm' from the string and than convert it to integer and than compare from from the same column: e.g #Size1 <= size_column and #size2 >= size_column:
Here's my query to trim and convert, but its giving me errors.
SELECT DEVICE_NO,
CASE [Rms_Size]
WHEN
(SELECT RMS_SIZE FROM DW_DATA.DBO.DIM_DEVICE WHERE
Ltrim(Rtrim(Rms_Size)) LIKE '%mm')
THEN
(SELECT SUBSTRING(Rms_Size,1,LEN(rms_size)-2)
FROM DW_DATA.DBO.DIM_DEVICE
where Ltrim(Rtrim(Rms_Size)) LIKE '%mm')
ELSE
RMS_SIZE
END
AS RMS_SIZE
FROM
DW_DATA.DBO.DIM_DEVICE
Try this -:
SELECT
DEVICE_NO,
CASE
WHEN
LTRIM(RTRIM(Rms_Size)) LIKE '%mm'
THEN
SUBSTRING(Rms_Size,1,LEN(rms_size)-2)
ELSE
RMS_SIZE
END
AS RMS_SIZE
FROM DW_DATA.DBO.DIM_DEVICE
create table mytable(
mystring varchar(100))
insert into mytable values('100mm')
insert into mytable values('100')
create Function removeChars(#mainString VarChar(100))
Returns VarChar(1000)
AS
BEGIN
WHILE PatIndex('%[^0-9]%', #mainString) > 0 BEGIN
Set #mainString = Stuff(#mainString, PatIndex('%[^0-9]%', #mainString), 1, '')
END
Return #mainString
END
select *
from mytable
where dbo.removeChars(mystring) >50