Update String Columns without Using Single Quotations - General Question - sql-server

UPDATE CustomerPhone
SET PhoneTypeID = 7, PhoneNumber = 999-444
WHERE CustomerID = 500 AND PhoneNumber = 9-1-1;
PhoneNumber is of type varchar(20) whereas PhoneTypeID and CustomerID are of type int. I'm running the above statement in SQL Server, it works fine.
I wonder how come it works? I thought any string value has to be put between '...'

SQL Server will CAST or CONVERT the value that you pass it, when you specify a value that isn't of type that you expect.
i.e. Try:
SELECT * FROM CustomerPhone WHERE PhoneTypeID = '7'
Here SQL Server will take your string '7' and try to convert to the appropriate type of int, smallint, tinyint (whatever appropriate).

Related

Cast / convert a column but getting error

I have a column in database table defined as varchar(1000) null
In one of the situations, the data is entered as N/A - so I can force to ignore all values and use null.
But there are some values which I want to use.
If I use cast, convert, try_cast, tryconvert, to varchar all fails, but if I do it to int, it works, but the try cast, try convert works.
I am not sure why it is failing when I use try_cast and it says:
convert failed to convert N/A value to int.
Even I am not converting it to INT
Try the following:
DECLARE #test_val AS varchar(100) = 'N/A'
SELECT TRY_CAST(#test_val AS int)
This gives a result of NULL
DECLARE #test_val AS varchar(100) = '3'
SELECT TRY_CAST(#test_val AS int)
Gives a result of 3.
It may be that your SQL has a syntax error.

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

t-sql view conversion failed when filtering on converted column

I am trying to create view by filtering some table, and include some converted to different type column into select list. View filter excludes from result set rows in which this column can not be converted to that type. Then I select rows from this view and filter rows using this converted column. And I always get error Conversion failed when converting the nvarchar value '2aaa' to data type int
SQL Fiddle
MS SQL Server 2008 Schema Setup:
create table _tmp_aaa (id int identity(1, 1), value nvarchar(max) not null)
go
insert _tmp_aaa (value) values ('1111'), ('11'), ('2aaa')
go
create view _tmp_v_aaa
as
select id, cast(value as int) as value from _tmp_aaa where value like '1%'
go
Query 1:
select * from _tmp_v_aaa where value = 11
Are there any workarounds?
Add to your view ISNUMERIC to check if string is numeric value:
CREATE VIEW _tmp_v_aaa
AS
SELECT
id,
[value] = CAST((CASE WHEN ISNUMERIC([value]) = 1 THEN [value] ELSE NULL END) AS INT)
FROM _tmp_aaa
WHERE [value] LIKE '1%'
AND ISNUMERIC([value]) = 1
I tried some tricks... Obviously the optimizer tries to hand down your where criterium where it is not yet tranformed. This is one problem to be solved with a. multi-statement function. Their biggest disadvantage is the advantage in this case: the optimizer will not look into it, but just take their result "as is":
create function fn_tmp_v_aaa()
returns #tbl table(id INT, value INT)
as
BEGIN
INSERT INTO #tbl
select id, cast(value as int) as value from _tmp_aaa where value like '1%'
RETURN;
END
select * from dbo.fn_tmp_v_aaa() where value=11;
If you look at the execution plan , predicates are passed down to the table something like....
And your query gets translated to something like .....
select id, cast(value as int) as value
from tmp_aaa
where CONVERT(INT, value,0) like '1%'
AND CONVERT(INT, value,0) = CONVERT(INT, 11,0)
Now if you run this query you will get the same error you get when you query against the view.
Conversion failed when converting the nvarchar value '2aaa' to data type int.
When the predicate CONVERT(INT, value,0) like '1%' is converted , you have INT on one side of the expressions and varchar on another, INT being the higher precedence, sql server tries to convert whole expression to INT and fails hence the error message.

Short guid in SQL Server / converting from a character string to uniqueidentifier

I need to create a column witch will contain short guid. So I found out something like this:
alter table [dbo].[Table]
add InC UNIQUEIDENTIFIER not null default LEFT(NEWID(),6)
But I get the error:
Conversion failed when converting from a character string to uniqueidentifier.
I've been trying
LEFT(CONVERT(varchar(36),NEWID()),6)
and
CONVERT(UNIQUEIDENTIFIER,LEFT(CONVERT(varchar(36),NEWID()),6))
But I am still getting the same error.
There is no such thing as "short guid". Guid, or uniqueidentifier is a 16 byte data type. You can read about it in MSDN. It means that the length must always be 16 bytes and you cannot use 6 characters as you are trying to do.
In the same MSDN article you can find description how you can initialize this type:
A column or local variable of uniqueidentifier data type can be
initialized to a value in the following ways:
By using the NEWID function.
By converting from a string constant in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, in which each x is a
hexadecimal digit in the range 0-9 or a-f. For example,
6F9619FF-8B86-D011-B42D-00C04FC964FF is a valid uniqueidentifier
value.
In your case you are trying to convert only 6 characters to uniqueidentifier which obviously fails.
If you want to use just 6 characters, just use varchar(6):
alter table [dbo].[Table]
add InC varchar(6) not null default LEFT(NEWID(),6)
Keep in mind that in this case this guid is not guaranteed to be unique.
Using CRYPT_GEN_RANDOM instead of NEWID can improve random distribution of the string.
SELECT LEFT(CAST(CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER) AS VARCHAR(50)), 6)
I just made this one since I couldn't find a good answer on the internet.
Please keep in mind this is a 64 bit representation of a 128bit value, so it has twice the collision possibilities that a real GUID would have. Does not handle 0.
Function takes a NEWID value: 6A10A273-4561-40D8-8D36-4D3B37E4A19C
and shortens it to : 7341xIlZseT
DECLARE #myid uniqueidentifier= NEWID()
select #myid
DECLARE #bigintdata BIGINT = cast(cast(reverse(NEWID()) as varbinary(max)) as bigint)
DECLARE #charSet VARCHAR(70) = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE #cBase int = LEN(#charSet)
DECLARE #sUID varchar(22) = ''
DECLARE #x int
WHILE (#bigintdata <> 0)
BEGIN
SET #x = CAST(#bigintdata % #cBase as INT) + 1
SET #bigintdata = #bigintdata / #cBase
SET #sUID = SUBSTRING(#charSet, #x, 1) + #sUID;
END
SELECT #sUID

Converting varchar to int, SQL Server

I have code like this:
CREATE FUNCTION gantistok (#id VARCHAR(8),
#id_t INT)
RETURNS INT
BEGIN
DECLARE #tahu INT,
#tempe INT,
#hasil INT;
SELECT #tahu = CONVERT(INT, stok)
FROM barang
WHERE id_barang = #id;
SELECT #tempe = CONVERT(INT, jumlah)
FROM det_trans
WHERE id_det_trans = #id_t;
SET #hasil = #tahu - #tempe;
RETURN #hasil
END
Why doesn't it work? I am getting this error:
Msg 402, Level 16, State 1, Procedure gantistok, Line 5
The data types text and varchar are incompatible in the equal to operator.
you are using wrong syntax
it should be
CONVERT(expr,type)
and type must be SIGNED [INTEGER]
REFERENCE
MySQL? SQL Server? which one?
What is type of id_barang stok for table barang?
Guessing the problem expression is id_barang=#id
The SQL Server convert() function does not allow convert TEXT to int(INT4).
problem is on id_barang = #id.
id_barang contains a value that RDBMS is not able to convert to integer.
id_barang is a varchar.
So if you can't convert id_barang to integer, then you have to convert #id to varchar in the query:
SELECT #tahu = CONVERT(INT, stok)
FROM barang
WHERE id_barang = CONVERT(varchar(50), #id);
I'm using varchar(50) because I don't know what kind of varchar exactly id_barang is.
I would suggest to always do it this way.
Even if id_barang would not contain non-integer values at the moment...it's still a text column!
Someone could insert a non-integer value anytime, so I would always make sure that my queries will work in this case as well.

Resources