SQL Server 2005 XML Query problem with ".exist" method - sql-server-2005

I have this XML Query in SQL Server 2005:
SElECT XmlField FROM tablename WHERE xmlField.exist('(/Root/Name[id="10")[1]') = 1
However, I want to replace the value "10" with a parameter that I pass to the Stored Procedure. How do I achieve this? I have tried using "#variablename" but it doesn't work.
Thanks in advance.

Probably, you want to have something like
SELECT XmlField FROM tablename WHERE xmlField.exist('(/Root/Name[id="{ sql:variable("#variablename") }")[1]') = 1
See http://msdn.microsoft.com/en-us/library/ms188254(v=SQL.100).aspx for how to access variables and columns in XQuery in SQL Server.

After a few minutes of hair pulling...i found an answer...
Result_XML.exist('(/Root/Name[id="{sql:variable("#myId")}"])[1]') = 1
should be written as
Result_XML.exist('(/Root/Name[id=(sql:variable("#myId"))])[1]') = 1
I replaced the "{ and }" with ( and ) to enclose the sql:variable keyword.

There is one more thing I found out about by many many trials: if your variable is a char value, if you declare it in your sql statement, it should be varchar, not char.
This sql didn't return any results:
DECLARE #myparam char(50)
SET #myparam = 'someval'
...
WHERE
t.c.exist('/root/child[text() = sql:variable("#myparam ")]') = 1
But this did:
DECLARE #myparam varchar(50)
SET #myparam = 'someval'
...
WHERE
t.c.exist('/root/child[text() = sql:variable("#myparam ")]') = 1
Maybe this is obvious, but I spent some time before I figured the reason why no records would be returned.

Related

concat with left in sql

i have two columens in the same table:
Column A :abcdef
Column B :12345
I want Column A value to be replaced by :
abcdef123
therefore i want all the data from column A plus the 3 first digit from column B.
I am stuck big time. I use Microsft SQL server Mgt Studio.
any help is welcome.
thanks
try this
set ColumnA=(select CONCAT(ColumnA,LEFT(ColumnB,3)))
as simple as this:
update table set ColumnA = ColumnA + LEFT(ColumnB, 3)
Use LEFT string function :
DECLARE #colA VARCHAR(100) = 'abcdef'
DECLARE #colB VARCHAR(100) = '12345'
SELECT #colA + LEFT(#colB,3)
Update Table_name SET ColumnA = ColumnA+LEFT(ColumnB,3)

SELECT statement having where clause with dynamic condition

I have a small select query which picks data from a table as per the parameter passed to a procedure.
DECLARE #flgParam bit
.
.
SELECT *
FROM tablename
WHERE flgRequired like <If #flgparam is 0 then 1 or zero , Else 1>
what is the best way to construct the where clause
I'm thinking something like this:
SELECT *
from tablename
where #flgparam is null or #flgcolumnval = #flgparam;
#flgparam is declared as a bit, so it can only take on the values of NULL, 0, and 1.
EDIT:
I'm trying to understand the logic. Adapted for the right names:
SELECT *
from sample
where (#flgparam = 0 and flgRequired is not null) or
(coalesce(#flgparam, 1) = 1 and flgRequired = 1)
The like is unnecessary; you can do strict equality.
A bit rough, but it should work, based on requirements:
select
S.itemname
,S.flgrequired
from
sample S
where
(S.flgRequired >= #flgParam)
Tested on sqlfiddle.
You cant use variables to substitute columns in the querys, to achieve that you should create your query as a string #QUERY and execute it using exec #QUERY

Convert linq statement to sql

I am deprecating a project from linq coding back to sql stored procedures. (My company refuses to upgrade our sql 2000 database.) I am stuck on this current code trying to convert it to sql. Can anyone help with this?
Dim ICD9Codes = (
From a In Linq2Db.ICD9Codes
Where IIf(String.IsNullOrEmpty(Variable1), 1 = 1, a.Code.StartsWith(Variable1))
Select a).ToList
I am stuck on the 'IIF' statements converting it where the 'where' clause only uses the if statement if the value is not null.
To convert this into a SP you'll need to make Variable1 a parameter. The IIf part could be addressed in the WHERE clause, like this:
CREATE PROCEDURE [procedure_name] #variable1 varchar(50)
AS
BEGIN
SELECT *
FROM ID9Codes
WHERE LEN(LTRIM(RTRIM(ISNULL(#variable1, '')))) = 0
OR Code lIKE #Variable1 + '%'
END

SQL conditional statement to include operator

I am passing parameters into a stored procedure. The one parameter is a varchar(50) that can be a string like " > 5000" and " <= 10000".
Here is some of the code:
....
....
#colourid int = 0,
#regionid int = 0,
#sellingPrice varchar(50) = '-1'
AS
SELECT
....
....
WHERE
(dbo.tbl_Listings.fld_ColourID = CASE WHEN #colourid = 0 THEN dbo.tbl_Listings.fld_ColourID ELSE #colourid END)
AND (dbo.tbl_Listings.fld_RegionID = CASE WHEN #regionid = 0 THEN dbo.tbl_Listings.fld_RegionID ELSE #regionid END)
AND
How do I add #sellingPrice to the WHERE? I can't mimic how it was done for the int parameters because it's not always going to use =. I need to say "if selling price is not -1 then fld_SellingPrice #sellingPrice".
The only way you can achieve that is by using dynamic SQL, building up your query in a local variable and then executing it via (preferably) sp_executesql.
So something like
DECLARE #sql nvarchar(MAX)
SET #sql = 'SELECT .... WHERE ' + #sellingPrice
sp_executesql #sql
However, this really does open you up to the possibility of SQL injection, and therefore you have to either
a. Be very sure that the procedure will only be called by callers you trust fully
b. Add protection for badly formed parameters within your procedure, which is much harder than it sounds
c. Find a different way to approach the problem entirely.
If you know you are going to have a general set of comparisons to use, I would create a parameter per comparison in your SP and use them as needed. So your SP might have
#greaterThan int,
#lessThan int,
#equalTo int
Then in the SP you could do
if #greaterThan IS NULL
SELECT #greaterThan = MAX(field) FROM table -- or some arbitrary value that will always evaluate to true
if #lessThan IS NULL
SELECT #lessThan = MIN(field) FROM table
Then just use those in your WHERE clause. Otherwise, as posted, you're going to have to do dynamic SQL by building an SQL string with the pieces of the WHERE clause.
I would use a from and a to variable.
So when you want less than 5000, you set to variable = 5000 and leave from blank
....
....
#colourid int = 0,
#regionid int = 0,
#fromsellingprice int = 5000
#tosellingprice int = null
AS
SELECT
....
....
WHERE
(dbo.tbl_Listings.fld_ColourID = CASE WHEN #colourid = 0 THEN dbo.tbl_Listings.fld_ColourID ELSE #colourid END)
AND (dbo.tbl_Listings.fld_RegionID = CASE WHEN #regionid = 0 THEN dbo.tbl_Listings.fld_RegionID ELSE #regionid END)
AND
sellingPrice >= coalesce(#fromsellingprice, sellingprice)
and sellingPrice <= coalesce(#tosellingprice, sellingprice)
You can't do this directly in SQL - the parameter will not be parsed and interpreted as part of the query with predicates.
The only way to do this (passing in the operator) is to use dynamic SQL, which comes with its own pitfalls.
You may consider passing in a parameter for what operator to use and have a bunch of if sections for each supported parameter - this may be worse than dynamic SQL.

SQL Server, Select CASE with different casting

I want to do a select that do a cast only for a specific ID but it doesn't seems to work.
Example :
SELECT
CASE
WHEN(#ID <> 1) THEN Code
WHEN(#ID = 1) THEN Cast(Code AS int)
END Code FROM ....
Any Idea ?
Why do want to do this? A SQL Server expression has a single fixed type. In other words, a single expression can't be varchar(50) or int depending on how the expression is evaluated. You could cast each case to sql_variant, but that may or may not make sense based on what you're trying to do.
EDIT
If you are executing this query from a stored procedure, you could create an IF..ELSE block to execute a different version of the query based on the value of #ID. For example:
IF (#ID = 1) BEGIN
SELECT Cast(Code AS int) AS Code FROM ...
END
ELSE BEGIN
SELECT Code FROM ...
END
It works for me. Check if the #id is of type int and if all values of column Code can be casted to int.
UPDATE If you have a value that can't be casted to int, your query won't work.
So you can write 2 different queries.
Smth like
IF #id = 1 THEN
SELECT code ...
ELSE
SELECT Cast(Code AS int) as Code
You could have also written:
select case when #ID = 1 then CAST(Code as int) else Code end as Code
from...
By the way, any data containing alphabetic characters won't cast to int.
Perhaps could we better help you if you tell us what you want to achieve, with some sample data provided?