SQL Select column tinyint - sql-server

I have a table with a column:
txntype (tinyint, not null)
I'm doing a select where value of txntype is equal to 9:
where CAST(txntype as varchar(3)) = '9'
but is throwing an error:
Insufficient result space to convert uniqueidentifier value to char.
I also tried:
where ISNUMERIC(txntype) = 9
but no records are selected when query is executed. Any ideas?

Can you add the create statement of that table and the entire select statement, because it seems that either the column has been declared as a uniqueidentifier column or your select is doing something with the value of another column than the one you are using in your where clause.
Also, the ISNUMERIC() function returns a bit (0 or 1) indicating if a value can actually be converted to a numeric datatype. Comparing it with the value 9 will always yield "false" for that piece of the where clause.
If the column is actually a numeric type, you don't have to cast the value in the where clause either way.
where [txntype] = 9
That is enough if the column is really a tinyint. And that's also the reason you need to be looking at other parts of the query in order to find the cause of the error.

You don't need to use cast or isnumeric
Just simply txntype = 9

Related

replace .0 on varchar data type

I have a varchar column that has numbers with .0
This column has both numeric data and non-numeric data.
I first tried to convert data type to integer, but since there is non-numeric data type, it would not let me.
How do I remove .0 (from all numbers that has .0)?
So, for example, 100.0 should be 100
I am not trying to use select, cast or truncate as I need to actually modify the existing data.
Thanks.
Since the column has both numeric and non-numeric data it is not enough to just check if it ends with '.0'.
You should also check if it is a numeric value, which can be done with TRY_CAST():
UPDATE tablename
SET col = LEFT(col, LEN(col) - 2)
WHERE col LIKE '%.0' AND TRY_CAST(col AS FLOAT) IS NOT NULL
See the demo.
Assuming you want to update your table...
where x = your table name
yourfieldname = the field name you need to update.
.
UPDATE table X
SET yourfieldName = left(yourfieldname,len(yourieldName)-2)
WHERE right(yourfieldName,2)='.0')
-- or perhaps where yourfieldname like '%.0' would be faster...
Should: update all fields ending in .0 would need to test to see which where clause would be faster depending on indexes. if speed is a consideration. If not; and this is a 1 and done... does it matter?
Be sure to test on a subset/copy table!
Assumes you don't have a spaces after the .0... or any non-display characters.. If you do you'll need to trim off the spaces and replace the non-display characters with empty string ''
Just another option
Example
Declare #YourTable table (SomeCol varchar(50))
Insert Into #YourTable values
('100.0')
,('1001.0')
,('Not Numeric')
,('-200.05')
,('10,250.0')
Update #YourTable
set SomeCol = format(try_convert(money,SomeCol),'#.######')
From #YourTable
Where try_convert(money,SomeCol) is not null
The Updated Table
SomeCol
100
1001
Not Numeric
-200.05
10250

Conversion failed when converting the vardhar value 'abc' to data type int

I am inserting data from one table to another so when inserting I got above error mentioned in title
Insert into dbo.source(
title
)
Select
Title from dbi.destination
title in dbo.source table is of INT data type and title in dbo.destination table is of Varchar data type and I have data like abc, efg, etc. in the dbo.destination table.
So how to solve this now or is it possible to convert and insert values?
You can use SQL Server try_cast() function as shown below. Here is the official documentation of TRY_CAST (Transact-SQL).
It Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
Syntax
TRY_CAST ( expression AS data_type [ ( length ) ] )
And the implementation in your query.
INSERT INTO dbo.source (title)
SELECT try_cast(Title AS INT)
FROM dbi.destination
Using this solution you need to be sure you have set the column allow null true otherwise it will give error.
If you do not want to set the allow null then you need minor changes in select query as shown below - passing the addition criteria to avoid null values.
Select ... from ... where try_cast(Title AS INT) is not null
You must use isnumeric method of SQL for checking is data numeric or not
CONVERT(INT,
CASE
WHEN IsNumeric(CONVERT(VARCHAR(12), a.value)) = 1 THEN CONVERT(VARCHAR(12),a.value)
ELSE 0 END)
Think about your data types - obviously you cannot have a text string like 'abc' in a column that is defined to hold integers.
It makes no sense to copy a string value into an integer column, so you have to confirm how you want to handle these - do you simply discard them (what is the impact of throwing data away?) or do you replace them with some other value?
If you want to ignore them and use NULL in place then use:
INSERT dbo.Source (Title)
SELECT CASE
WHEN ISNUMERIC(Title) = 1 THEN CAST(Title as INT)
ELSE NULL
END
FROM dbo.Destination
If you want to replace the value then simply change NULL above to the value you want e.g. 0
You can use regex to root out non numeric characters
Insert into dbo.source(
title
)
Select
case when Title not like '%[^0-9]%' then null else cast(Title as int) end as Title
from dbi.destination
Just filter only numeric field from destination table like as below:
Insert into dbo.source(
title
)
Select
Title from dbi.destination
where ISNUMERIC(Title) = 1

Different aggregate functions depending on datatype

I have a T-SQL script that returns all columns in a table, along with datatype and max value MAX(DATALENGTH)) fetching it from sys.columns and sys.types.
However the max value will always be 4 for ints, since ints uses 4 bytes. In this case I'd rather have the highest numeric value of the column.
I figured I might change my query to use DataLength for string-based columns, and a MAX() for number based columns, however I run into some problems before I even get there:
Minified example code
DECLARE #A bit = 1
SELECT CASE WHEN 1=1 THEN MAX(DATALENGTH(#A)) ELSE MAX(#A) END
I would expect to receive the number 1 given that 1=1 is true.
Instead I get an error
Operand data type bit is invalid for max operator.
I understand that you can't run MAX(#A) on a bit, but that's not what I'm trying to do. My goal is to run different aggregate functions depending on the datatype.
How can I solve this?
My goal is to run different aggregate functions depending on the datatype.
This will fail because you will get invalid cast errors or will get implicit conversions to the highest precedence data type
Your use of bit is irrelevant here
smalldatetime has the highest precedence so this code gives odd results when mixing datatypes
DECLARE #foo table (
intval int,
floatval float,
datetimeval smalldatetime)
INSERT #foo VALUES
(1, 1.567E2, '2017-07-31'),
(2, 2.0, '2017-08-01');
DECLARE #Switch int;
SELECT
CASE
WHEN #Switch=1 THEN MAX(intval)
WHEN #Switch=2 THEN MAX(floatval)
ELSE MAX(datetimeval)
END
FROM
#foo
SET #Switch = 1
1900-01-03 00:00:00
SET #Switch = 2
1900-06-06 16:48:00
SET #Switch = 3
2017-08-01 00:00:00
In this case, you are missing a cast :
SELECT CASE WHEN 1=1 THEN MAX(DATALENGTH(#A)) ELSE MAX(CAST(#A as bigint)) END

SQL Server - Cast invalid value to int

Is there any way to deal with SQL casts if the input data is corrupt?
Let's say I have a column of datatype NVarchar(10) and want to cast this column to int.
Let's also say that some of the nvarchar values are corrupt, so they can't be converted to int.
Is there any way to silently ignore these, default them to 0 or some such?
DECLARE #t TABLE (Numbers VARCHAR(20))
INSERT INTO #t
VALUES
('30a'),('30'),('100'),
('100a'),('200'),('200a')
SELECT CASE
WHEN ISNUMERIC(Numbers) = 1
THEN CAST(Numbers AS INT) ELSE NULL END AS Number
FROM #t
ISNUMERIC Function returns 1 when it is an integer value you can use this function.
Result
Number
NULL
30
100
NULL
200
NULL
it will cast the integer values to INT and ignore the values that cannot be cast to Int
Try this with PatIndex() function:
select id, val
from t
where patindex('%[^0-9]%',val) = 0
Note: above query is filtering out corrupted values, if you need to bring them in with 0 values, please use a case expression as below.
select id, case when patindex('%[^0-9]%',val) = 0
then convert(int, val)
else 0 end val
from t
Fiddle demo for both queries
I'll be the unpopular one and advise REGEX because ISNUMERIC, while sometimes useful, doesn't catch everything. This answer on SO excellently covers some REGEX concepts, for instance:
One numeric digit
Probably the easiest one of the bunch:
WHERE Column LIKE '[0-9]'
For more details, here's a useful REGEX workbench by Phil Factor and Robyn Pae.

Handling NULLs in SQL query

What is the right practice of checking NULLs in SQL Case ?
1) Using ISNULL()
WHEN (ISNULL(TABLE.COLUMN,0) > 0) THEN ....
2) Using IS NULL
WHEN TABLE.COLUMN IS NOT NULL THEN ....
If you are checking any condition then always use 'is null' and if replacing any value with a different one, then use isnull(a,b).
Check the following -
http://msdn.microsoft.com/en-us/library/ms184325.aspx
Read the last line specially!!!
Second one is right if you want to check for null value in SQL case..
Both are correct if the values in the column are either greater than 0 or null.
You can refer to this post if you want to know about the weird behavior of nulls in SQL Server.
This is also another approach to check for NON NULL values.
Checking for length of the column if it is greater than 1 or equal 1 then its a NON NULL
value.
declare #emp table
(
fname varchar(50)
);
INSERT into #emp VALUES('vishwanath');
INSERT into #emp VALUES('chetan');
INSERT into #emp VALUES(NULL);
INSERT into #emp VALUES(NULL);
SELECT * FROM #emp
where len(fname)>=1 and fname<>'';
Gives..
fname
--------------------------------------------------
vishwanath
chetan
when you are checking whether a column is null or not it is better to use
col IS NULL
when you use ISNULL(TABLE.COLUMN,0) > 0) function , null values have to be converted to zero fist then should take all values greater than zero
this function is useful in another occasion. lets say if I want to return all the null values as well as the negative values.
so the query would be
select * from table where col is null or col<0
this can be re-written as
select * from table isnull(col,-1)<0
Both are correct in there cause, however ISNULL can be helpfull when you want to use a constant value instead of NULL in that column while calculating SUM, average, etc.
For example you can check :http://www.w3schools.com/sql/sql_isnull.asp
Due to this feature I personally use ISNULL/COALESCE for calculation purposes.

Resources