Can't find a value in a column - sql

I'm looking for an image in a column, I know it's there. But when I select, I can't find it. Does someone know what I am doing wrong?
SELECT
CONVERT(VARBINARY(MAX), Picture),
COUNT(*) AS Count -- convert(nvarchar,(MAX(employeeid)))
FROM
TABLENAME
GROUP BY
CONVERT(VARBINARY(MAX), Picture)
HAVING
COUNT(*) > 1
ORDER BY
Count
I get a result and a count 4. When I query the table using
Select CONVERT(VARBINARY(MAX), Picture),employeeid from TABLENAME where CONVERT(VARBINARY(MAX), Picture) = 'value from result 1'
and the value in a select statement, I get nothing.

If I understand correctly, and you want to identify rows where the same image is used more than once then you can do:
WITH CTE AS(
SELECT employeeid,
Picture,
COUNT(employeeid) OVER (PARTITION BY Picture) AS Entries
FROM YourTable)
SELECT *
FROM CTE
WHERE Entries > 1;
Also, I suspect your query didn't work because you had:
CONVERT(VARBINARY(MAX), Picture) = 'value from result 1'
You're implying that you put the value of the previous varbinary in literal string quotes. The values 0x01 and '0x01' are not the same (SELECT CASE WHEN 0x01 = '0x01' THEN 1 ELSE 0 END; returns 0). '0x01' is a string representation of a varbinary, however, if you cast that value to a varbinary you get 0x30783031 (SELECT CASE WHEN 0x30783031 = '0x01' THEN 1 ELSE 0 END; returns 1).

You get nothing because you are performing a STRING search on BINARY data.
where CONVERT(VARBINARY(MAX), Picture) = 'value from result 1'
The left part is Binary, the right part is a string (CHAR)
You should convert again your VARBINARY to VARCHAR to perform the string search :
Select CONVERT(VARBINARY(MAX), Picture),
employeeid
from TABLENAME
where CONVERT(varchar(max),CONVERT(VARBINARY(MAX), Picture),1) = 'value from result 1'
The ,1 is the "style" that tells SQL server to return the string in binary notation, ie with 0x appended at the begining, which is how your "binary strings" are supposed to be returned by your first query. See Binary styles on CAST and CONVERT (Transact-SQL)

Related

How to combine 2 SELECT statements with different returning data-types in 1 query?

I have tried using UNION ALL query, but it needs the same returning data-type. In the example below name is TEXT while debits is json it leads to an error with UNION ALL-
So how do I return the combined result of name and debits in one query ?
'''
(SELECT
name
FROM
mytable
WHERE grade= % s)
UNION
ALL
(SELECT
debits
FROM
mytable
WHERE balancesheet= % s)
;
'''
psycopg2.errors.DatatypeMismatch: UNION types text and json cannot be matched .
Like you stated correctly, and the error msg instructs: you need compatible types. One way to solve it: convert text to json with to_json():
SELECT to_json(name) AS name_and_debit
FROM mytable
WHERE grade = %s
UNION ALL
SELECT debits
FROM mytable
WHERE balancesheet = %s
;
Or json to text with a plain cast: debits::text. See:
Postgres data type cast

SQL find error value on table or skip error

I have over thousands data on my table, in this case i want to change data type hexadecimal value into integer. here's table example :
hex int
000001CA |
000001D3 |
000001F5 |
this is my query :
UPDATE table
SET int = CONVERT(int, CONVERT(varbinary, hex, 2))
when i execute the query i get error message that some value error failed converting data type but i dont know which one because there are many data on the table. Is there a way to find the error value or just skip the error and continue other value ?
Thanks for the help.
You can simply change it to:
UPDATE table
SET int = TRY_CONVERT(int, TRY_CONVERT(varbinary, hex, 2))
TRY_CONVERT will attempt to convert the value and if it cannot, return a NULL.
Another option is to select the hex values from your table and use
WHERE TRY_CONVERT(int, TRY_CONVERT(varbinary, hex, 2)) IS NOT NULL
to get all the valid, convert-able values. Then you can run your update knowing it is only using valid values.
You can use TRY_CONVERT to find the records that are failing to convert. This function will return NULL if conversion fails.
Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
https://learn.microsoft.com/en-us/sql/t-sql/functions/try-convert-transact-sql?view=sql-server-ver15
select t.*
from table t
where try_convert(int, CONVERT(varbinary, t.hex, 2)) is null;
There's no problem with your Update statement except for the table name(table). Even a table with this name cannot be created, but if you convert it to [table], then the statement will be succesfull :
UPDATE [table]
SET int = CONVERT(int, CONVERT(varbinary, hex, 2)); -- case hex is type VARCHAR
SELECT *
FROM [table];
int hex
458 000001CA
467 000001D3
501 000001F5
OR
UPDATE [table]
SET int = CONVERT(int, hex) -- case hex is type VARBINARY
SELECT *
FROM [table];
int hex
458 0x000001CA
467 0x000001D3
501 0x000001F5
Demo
P.S.:TRY_CONVERT(int, TRY_CONVERT(varbinary, hex, 2)),which's stated within the other answers, would return the same result.

how to convert the output of sub query into numeric

select rptName
from RptTable
where rpt_id in (
select LEFT(Reports, NULLIF(LEN(Reports)-1,-1))
from repoAccess1
where uid = 'VIKRAM'
)
this is my sql query In which i have use the sub query to access selected field
in this sub query returns
select LEFT(Reports, NULLIF(LEN(Reports)-1,-1))
from repoAccess1
where uid = 'VIKRAM'
Returns
1,2
that means the query should be like
select rptName
from RptTable where rpt_id in (1,2)
But i m getting this error
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to numeric.
could anyone tell me ow to modify to get exact ans
It's a little hard to tell without the concrete table definitions, but I'm pretty sure you're trying to compare different data types to each other. If this is the case you can make use of the CAST or the CONVERT function, for example:
SELECT
[rptName]
FROM [RptTable]
WHERE [rpt_id] IN
(
SELECT
CONVERT(int, LEFT([Reports], NULLIF(LEN([Reports]) - 1, -1)))
FROM [repoAccess1]
WHERE [uid] = 'VIKRAM'
)
UPDATE: Since you have updated your question: The LEFT function returns results of either varchar or nvarchar data type. So the resulting query would be
SELECT
[rptName]
FROM [RptTable]
WHERE [rpt_id] IN('1', '2')
Please note the apostrophes (is this the correct term?) around the values. Since [rpt_id] seems to be of data type int the values cannot implicitly be converted. And that's where the aforementioned CAST or CONVERT come into play.
If I understand correctly, the subquery is returning a single row with a value of '1,2'. This is not a number, hence the error.
Before continuing, let me emphasize that storing values in comma delimited string is not the SQL-way of doing things. You should have one row per id, with proper types and foreign keys defined.
That said, sometimes we are stuck with other people's really bad design decisions. If this is the case, you can use LIKE:
select rptName
from RptTable r
where exists (select 1
from repoAccess1 a
where a.uid = 'VIKRAM' and
',' + a.reports + ',' like '%,' + cast(r.rpt_id as varchar(255)) + ',%'
);
select rptName
from RptTable
where rpt_id in (
select CAST(LEFT(Reports, NULLIF(LEN(Reports)-1,-1)) AS INT) as Val
from repoAccess1
where uid = 'VIKRAM'
)
Your query would work fine when (LEFT(Reports, NULLIF(LEN(Reports)-1,-1)) ) returns either 1 or 2 since SQL Server implicitly converts the varchar value to numeric.
It seems there might be a data issue. One of the data returned by LEFT function is non-numeric. In order to find that particular record you can use isnumeric function. Try like this,
SELECT rptName
FROM RptTable
WHERE rpt_id IN (
SELECT LEFT(Reports, NULLIF(LEN(Reports) - 1, - 1))
FROM repoAccess1
WHERE uid = 'VIKRAM'
AND ISNUMERIC(LEFT(Reports, NULLIF(LEN(Reports) - 1, - 1))) = 1
)

Convert exponential to number in sql

I have a large amount of card tokens (16 digits) uploaded from xml file to sql-server. The problem is I see them as expression, sample below:
3.3733E+15
3.3737E+15
3.3737E+15
3.3737E+15
3.37391E+15
3.37391E+15
3.37398E+15
3.37453E+15
3.37468E+15
3.37468E+15
3.3747E+15
3.37486E+15
3.37486E+15
3.37567E+15
3.3759E+15
3.3759E+15
Any suggestion to change them to a 16 digit number? I have tried to change the data type, but got error"Conversion failed when converting the varchar value '3.37201E+15' to data type int"
Thanks for help!
Edit:
#X.L.Ant see my code below. I create this table from another one, which is just purely inserted from xml file. Is this may cause an error because some rows are empty in column TOKEN?
CREATE TABLE MULTICURRENCY_CHECK
(
TOKEN varchar(255)
)
/*Merges all card tokens into 1 column, as in xml they are spread across different columns*/
INSERT INTO MULTICURRENCY_CHECK
(
TOKEN
)
SELECT no FROM gpstransactionsnew2
UNION ALL
SELECT no19 FROM gpstransactionsnew2
UNION ALL
SELECT no68 FROM gpstransactionsnew2
UNION ALL
SELECT no93 FROM gpstransactionsnew2
UNION ALL
SELECT no107 FROM gpstransactionsnew2
UNION ALL
SELECT no121 FROM gpstransactionsnew2
SELECT REPLACE(TOKEN, 'OW1', ' ')
FROM MULTICURRENCY_CHECK
/*Converts exponential expression to number*/
SELECT CONVERT(numeric(16,0), CAST(TOKEN AS FLOAT))
FROM MULTICURRENCY_CHECK
Try to cast your string to float before converting it :
SELECT CONVERT(numeric(16,0), CAST(TOKEN AS FLOAT))
FROM MULTICURRENCY_CHECK
See this fiddle.
I don't know what's the format of those numbers in your XML source, but with the data you provide, you'll end up with 33733 for instance followed by a bunch of zeroes. If you have a bigger precision in your XML, maybe you should tweak your importing settings to keep this precision instead of trying to deal with that in the DB.
EDIT:
Try testing your strings with ISNUMERIC to avoid the casting errors you're getting. Adding a raw output of your column will allow you to check which value fails to convert (i.e. converts to 0).
SELECT TOKEN,
CONVERT(NUMERIC(16, 0), CAST(CASE
WHEN ISNUMERIC(TOKEN) = 1
THEN TOKEN
ELSE 0
END AS FLOAT))
FROM MULTICURRENCY_CHECK
For SQL Server 2012+, use TRY_CONVERT().
The use of ISNUMERIC() in xlecoustillier's edited answer does not protect against conversion failures.
Given the following scenario:
CREATE TABLE test(a varchar(100));
insert into test values ('3.3733E+15'),
('3.3737E+15'),
('3.37391E+30'), --fails conversion. included to demonstrate the nature of TRY_CONVERT().
('3.37398E+15'),
('3.37453E+15'),
('3.37468E+15'),
('3.3747E+15'),
('3.37486E+15'),
('3.37567E+15'),
('3.3759E+15');
SELECT TRY_CONVERT(numeric(16,0), CAST(a AS FLOAT))
FROM test
Results in only valid converted values:
---------------------------------------
3373300000000000
NULL
3373910000000000
3373980000000000
3374530000000000
3374680000000000
3374700000000000
3374860000000000
3375670000000000
3375900000000000
However:
SELECT a,
CONVERT(NUMERIC(16, 0), CAST(CASE
WHEN ISNUMERIC(a) = 1
THEN a
ELSE 0
END AS FLOAT))
FROM test
Fails with:
Conversion failed when converting the varchar value '3.3733E+15' to
data type int.
The issue is that all values in the 'a' column return 1 when passed to the ISNUMERIC() function.
SELECT CASE WHEN ISNUMERIC(a) = 1 THEN 'Yes' ELSE 'No' END as IsValueNumeric
FROM test
Try it on SQLFiddle and/or compare with xlecoustillier's sqlfiddle
SELECT colmn_name || '' FROM table_name
This should work.

Conversion failed when converting date and/or time from character string

Why does this statement succeed?
SELECT CAST('08:50' as time)
But this one fails? tmrec is an nvarchar(6) column and contains the same value '08:50'. This is making me crazy since last 1 hour.
SELECT TOP 1 CAST(tmrec as time)
FROM Instr
WHERE igrp = 'JD'
ORDER BY ino , smallin
This screenshot shows the 1st query's result. It contains 08:50. Yet the 2nd query throws error.
Edit:
Even this doesn't work which guarantees that conversion is applied only on fetched records:
SELECT CAST( tmrec as time)
FROM
(
SELECT TOP 1 tmrec
FROM [ccwise-courts].[dbo].[INSTR]
WHERE igrp = 'JD'
ORDER BY ino , smallin
) v
Generally, to look for bad data, you can use a query like this:
SELECT TOP(100) '-->' + REPLACE(tmrec, ' ', '*') + '<--bad'
FROM Instr
WHERE ISDATE(tmrec) = 0
And if you still cannot make it out, you can list out the specific ASCII code of the characters involved (here I go up to 6 per the question):
SELECT TOP(100) '-->' + REPLACE(tmrec, ' ', '*') + '<--bad',
Char1 = ascii(substring(tmrec,1,1)),
Char2 = ascii(substring(tmrec,2,1)),
Char3 = ascii(substring(tmrec,3,1)),
Char4 = ascii(substring(tmrec,4,1)),
Char5 = ascii(substring(tmrec,5,1)),
Char6 = ascii(substring(tmrec,6,1))
FROM Instr
WHERE ISDATE(tmrec) = 0
There is this Connect item that deals with SQL Server processing CAST on the SELECT clause before the WHERE filter has been applied. To overcome that, as also noted in the bug report, you can use a CASE statement:
CAST(CASE WHEN ISDATE(tmrec)=1 THEN tmrec END as time)