CAST error in a Where Clause - sql-server

On the query below I keep getting this error:
Cannot read the next data row for the dataset DataSetProject. (rsErrorReadingNextDataRow)
It appears to be the where clause, if I take it out it seems to work. So I added a cast to the where clause with no luck. Is there something special I need to do in the where clause to get this to work? Just an FYI this is in a report that is pulling an id from the url.
SELECT new_projects.new_projectsId AS ProjectId
, new_projects.new_name AS ProjectName
, new_projects.new_Description AS ProjectDescription
FROM
new_projects
LEFT OUTER JOIN new_projectsteps
ON new_projects.new_projectsId = new_projectsteps.new_ProjectSteps2Id
LEFT OUTER JOIN Task
ON new_projectsteps.new_projectstepsId = Task.RegardingObjectId
WHERE
(new_projects.new_projectsId = cast(#id AS UNIQUEIDENTIFIER))
Thanks!
EDIT:
The id in SQL is a Unique Identifier, the value of #id is being pulled from the querystring(url). So it would look like: &id='BC02ABC0-A6A9-E111-BCAD-32B731EEDD84'
Sorry for the missing info.

I suspect the single quotes are coming through. So either don't have them there by stripping them out before being passed to your parameter or use:
WHERE new_projects.new_projectsId = CONVERT(UNIQUEIDENTIFIER, REPLACE(#id, '''', ''));
If you try a direct comparison when the GUID contains other characters, you should get:
Msg 8169, Level 16, State 2, Line 1 Conversion failed when
converting from a character string to uniqueidentifier.
If this is not what's happening, then don't say "the id in SQL is a Unique Identifier" - show ALL of the code so we can try to reproduce the problem.

Related

SQL Server - add to this query to first check for existence of a string

I have an nvarchar field in my database called CatCustom which contains comma-separated 5-character codes. It can contain as little as one code, or as many as 20 codes, separated by commas.
Right now, I use this query to add a new 5-character code to the field in given records (in this case the new code is LRR01):
UPDATE dbo.Sources
SET CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
I need to add to this though: I need the record to be updated only if that 5-character code doesn't already exist somewhere in the CatCustom field, to ensure that code is not in there more than once.
How would I accomplish this?
EDIT: I really don't understand how this can be considered a duplicate of the suggested thread. This is a VERY specific case and has nothing to do with creating stored procedures and or variables. The alleged duplicated thread does not really help me - sorry.
Use STRING_SPLIT function to split the comma separated list and then add Not Exist condition in the WHERE clause like below
UPDATE dbo.Sources
SET CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
AND NOT EXISTS (SELECT 1 FROM STRING_SPLIT(CatCustom, ',') where value = 'LRR01')
UPDATE dbo.Sources
SET
CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE
SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
AND CatCustom NOT LIKE '%LRR01%';

Concat the values in a string with SQL Server

I want to select a list of items and part numbers for for each item as a string:
SELECT top 100 *
FROM ii
OUTER APPLY
(SELECT def, ( ipr.part_number + ',') as prt
FROM ipr
WHERE ii.item_id = ipr.item_id
FOR XML PATH('') ) PN
The error is:
[Error Code: 8155, SQL State: S0002] No column name was specified for
column 1 of 'PN'.
How can I fix this?
I think that your whole OUTER APPLY statement generates one XML for both default_part_number and concatenated string, which(the whole XML) doesn't have a name.
What you could try to do would be adding alias like this AS PN(TestThis).
However, I don't think that you're expecting result you're going to get. It would better if you'd give us some example data and expected output. It will be easier for us to solve your problem in that case.
The combination of XML and STUFF is funny but perfectly fitting to your needs.
First you concat your strings with the ', ' in front, then you must return your XML with ", TPYE). You must read the result with ".value()" and use STUFF to replace the first ', '.
You'll find a lot of exampels in the net...

SSIS Foreach Loop failure

I have created a lookup for a list of IDs and a subsequent Foreach loop to run an sql stmt for each ID.
My variable for catching the list of IDs is called MissingRecordIDs and is of type Object. In the Foreach container I map each value to a variable called RecordID of type Int32. No fancy scripts - I followed these instructions: https://www.simple-talk.com/sql/ssis/implementing-foreach-looping-logic-in-ssis-/ (without the file loading part - I am just running an SQL stmt).
It runs fine from within SSIS, but when I deploy it my Integration Services Catalogue in MSSQL it fails.
This is the error I get when running from SQL Mgt Studio:
I thought I could just put a Precendence Constraint after MissingRecordsIDs get filled to check for NULL and skip the Foreach loop if necessary - but I can't figure out how to check for NULL in an Object variable?
Here is the Variable declaration and Object getting enumerated:
And here is the Variable mapping:
The SQL stmt that is in 'Lookup missing Orders':
select distinct cast(od.order_id as int) as order_id
from invman_staging.staging.invman_OrderDetails_cdc od
LEFT OUTER JOIN invman_staging.staging.invman_Orders_cdc o
on o.order_id = od.order_id and o.BatchID = ?
where od.BatchID = ?
and o.order_id is null
and od.order_id is not null
In the current environment this query returns nothing - there are no missing Orders, so I don't want to go into the 'Foreach Order Loop' at all.
This is a known issue Microsoft is aware of: https://connect.microsoft.com/SQLServer/feedback/details/742282/ssis-2012-wont-assign-null-values-from-sql-queries-to-variables-of-type-string-inside-a-foreach-loop
I would suggest to add an ISNULL(RecordID, 0) to the query as well as set an expression to the component "Load missing Orders" in order to enable it only when RecordID != 0.
In my case it wasn't NULL causing the problem, the ID value which I loaded from database was stored as nvarchar(50), even if it was a integer, I attempted to use it as integer in SSIS and it kept giving me the same error message, this worked for me:
SELECT CAST(id as INT) FROM dbo.Table

Building dynamic query for Sql Server 2008 when table name contains " ' "

I need to fetch Table's TOP_PK, IDENT_CURRENT, IDENT_INCR, IDENT_SEED for which i am building dynamic query as below:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{1}]') AS CURRENT_IDENT, IDENT_INCR('[{1}]') AS IDENT_ICREMENT, IDENT_SEED('[{1}]') AS IDENT_SEED", pPrimaryKey, pTableName)
Here pPrimaryKey is name of Table's primary key column and pTableName is name of Table.
Now, i am facing problem when Table_Name contains " ' " character.(For Ex. KIN'1)
When i am using above logic and building query it would be as below:
SELECT (SELECT TOP 1 [ID] FROM [KIL'1]) AS TOP_PK, IDENT_CURRENT('[KIL'1]') AS CURRENT_IDENT, IDENT_INCR('[KIL'1]') AS IDENT_ICREMENT, IDENT_SEED('[KIL'1]') AS IDENT_SEED
Here, by executing above query i am getting error as below:
Incorrect syntax near '1'.
Unclosed quotation mark after the character string ') AS IDENT_SEED'.
So, can anyone please show me the best way to solve this problem?
Escape a single quote by doubling it: KIL'1 becomes KIL''1.
If a string already has adjacent single quotes, two becomes four, or four becomes eight... it can get a little hard to read, but it works :)
Using string methods from .NET, your statement could be:
sGetSchemaCommand = String.Format("SELECT (SELECT TOP 1 [{0}] FROM [{1}]) AS TOP_PK, IDENT_CURRENT('[{2}]') AS CURRENT_IDENT, IDENT_INCR('[{2}]') AS IDENT_ICREMENT, IDENT_SEED('[{2}]') AS IDENT_SEED", pPrimaryKey, pTableName, pTableName.Replace("'","''"))
EDIT:
Note that the string replace is now only on a new, third substitution string. (I've taken out the string replace for pPrimaryKey, and for the first occurrence of pTableName.) So now, single quotes are only doubled, when they will be within other single quotes.
You need to replace every single quote into two single quotes http://beyondrelational.com/modules/2/blogs/70/posts/10827/understanding-single-quotes.aspx

TSQL to insert an ascending value

I am running some SQL that identifies records which need to be marked for deletion and to insert a value into those records. This value must be changed to render the record useless and each record must be changed to a unique value because of a database constraint.
UPDATE Users
SET Username = 'Deleted' + (ISNULL(
Cast(SELECT RIGHT(MAX(Username),1)
FROM Users WHERE Username LIKE 'Deleted%') AS INT)
,0) + 1
FROM Users a LEFT OUTER JOIN #ADUSERS b ON
a.Username = 'AVSOMPOL\' + b.sAMAccountName
WHERE (b.sAMAccountName is NULL
AND a.Username LIKE 'AVSOMPOL%') OR b.userAccountControl = 514
This is the important bit:
SET Username = 'Deleted' + (ISNULL(
Cast(SELECT RIGHT(MAX(Username),1)
FROM Users WHERE Username LIKE 'Deleted%') AS INT)
,0) + 1
What I've tried to do is have deleted records have their Username field set to 'Deletedxxx'. The ISNULL is needed because there may be no records matching the SELECT RIGHT(MAX(Username),1) FROM Users WHERE Username LIKE 'Deleted%' statement and this will return NULL.
I get a syntax error when trying to parse this (Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'SELECT'.
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near ')'.
I'm sure there must be a better way to go about this, any ideas?
If your Users table already has an integer PK column, you can simply use this column to generate 'Deleted'+PK usernames.
Btw, would the SELECT RIGHT(MAX(Username),1) not fail after 10 users? Better to use SUBSTRING().
Is it strictly necessary to use incremental 'xxx' values? Couldn't you just use random values?
SET Username = Username + '_deleted_' + CAST(NEWID() AS char(36))
Additionally, it might be a bad idea to overwrite the login completely. Given that you disable the record, not delete it entirely, I assume that you need it for audit purposes or smth. like that. In this case, records with IDs like 'Deleted1234' might be too anonymous.
I suspect this would work better as a multi-step SQL statement, but I'm unsure if that's reasonable.
The error you're seeing is because you're trying to concatenate an int to a string, you're also adding 1. Your order of operations is all screwy in that set statement. This does what you're asking, but it will fail the minute you get more than 9 deleted entries.
SELECT 'DELETED' + CAST(
ISNULL(
CAST(
SELECT RIGHT(MAX(Username),1)
FROM #Users WHERE username LIKE 'DELETED%')
AS INT)
, 0) + 1 )
AS VARCHAR(3))
edit: sorry for the horrible formatting. Couldn't figure out how to make it readable.

Resources