Setting a SQL variable equal to column in UPDATE with xml - sql-server

Can anyone help me figure out what is wrong here?
I would like to set the value of the variable #Customer to a value of a column in the same row. I am assuming I am out of scope or something. The tag gets inserted but it is blank. If I manually set #customer to something, then it does get populated in the xml. There HAS to be a way to do this.
Declare #Customer varchar(500)
UPDATE Ore.RuleInfo
set #Customer=RG.[RuleGroupName], UserEntryXML.modify('
insert
<CustomerName>{sql:variable("#Customer")}</CustomerName>
into (UserEntry/Results/Customer)[1]')
From
Ore.RuleInfo RI
inner join ORE.RuleGroup RG on RG.RuleGroupID = RI.RuleGroupID

Instead of using sql:variable, use sql:column
DECLARE #tbl TABLE (x XML, customerName VARCHAR(100));
INSERT INTO #tbl
( x, customerName )
VALUES ( '<id>1</id><name>old1</name>', 'customer1' ),
( '<id>2</id><name>old2</name>', 'customer2' ),
( '<id>3</id><name>old3</name>', 'customer3' );
SELECT *
FROM #tbl
UPDATE #tbl
SET x.modify('
replace value of (/name/text())[1]
with sql:column("customerName")
')
SELECT *
FROM #tbl

Related

How to store the result of an select statement into a variable in sql server stored procedure

I have a condition like this:
IF #aaa = 'high'
set #bbb = select * from table1
else
set #bbb = select * from table2
I am going to use this variable (#bbb) throughout my stored procedure
is this possible to save a table into a variable?
I tried using temporary table but i am not able to assign it twice.
IF #aaa = 'high'
set #bbb = select * into #temp from table1
else
set #bbb = select * into #temp from table2
it shows #temp is already declared.
No, It is not work like that. You can declare a table variable and insert into inside it.
DECLARE #bbbTable TABLE(
Id int NOT NULL,
SampleColumn varchar(50) NOT NULL
);
insert into #bbbTable (Id,SampleColumn)
select Id,SampleColumn from table1
If the table1 and table2 are completely different tables, you should declare two different table variable;
DECLARE #bbbTable TABLE(
Id int NOT NULL,
SampleColumn varchar(50) NOT NULL
);
DECLARE #aaaTable TABLE(
Id int NOT NULL,
SampleColumn varchar(50) NOT NULL
);
IF #aaa = 'high'
insert into #bbbTable (Id,SampleColumn)
select Id,SampleColumn from table1
else
insert into #aaaTable (Id,SampleColumn)
select Id,SampleColumn from table2
You cant insert into a variable more than 1 value.
you can use Table Variable to reach your answer like this:
DELCARE #TableResult AS TABLE (Column1 INT, Column2 INT)
IF #aaa = 'high'
BEGIN
INSERT INTO #TableResult (Column1,Column2)
SELECT Column1FromTable, Column2FromTable
FROM table1
END
ELSE
BEGIN
INSERT INTO #TableResult (Column1,Column2)
SELECT Column1FromTable, Column2FromTable
FROM table2
END
Of course you can declare more than 2 columns.
You can store only 1 Column/Row to a variable.So you can't say *.
Suppose I want to store the value of Column1 from TableA to a variable, I can use this
SELECT #MyVariable = Column1 FROM TableA
But I Can't Say
SELECT #MyVariable = * FROM TableA
Even if there is only 1 column in the Table TableA.
Also If there is more than 1 record returned by the Select condition, then it will assign the First value to the Variable.
Or What you need is to store the entire Rows, you can Either use a Temporary table or a table variable.
Temporary Table
SELECT * INTO #Temp FROM TableA
Table Variable
DECLARE #MyVarTable TABLE
(
Column1 VARCHAR(50),
Column2 VARCHAR(50)
)
INSERT INTO #MyVarTable
(
Column1 ,
Column2
)
SELECT
Column1 ,
Column2
From MyTable
This Temporary Table and Table variable can be accessed in the same way you access the normal table using SELECT/UPDATE/DELETE Queries. Except :
Temporary tables are created for each session and automatically dropped when the session ends or the Query window is Closed
Table Variables exists only when you execute the Query. So before using the table variable in a query you need to declare the same

Remove Root XML nodes from default output of Sql Server statement

I want #MyActualXMLOut to look like #MyDesiredXMLOut... How? Thanks in advance!
#MyDesiredXMLOut =
<MyRequiredRoot>
<Property1>Value1</Property1>
<Property2>Value2</Property2>
</MyRequiredRoot>
#MyActualXMLOut
<_x0040_MyTableVar>
<MyXML>
<MyRequiredRoot>
<Property1>Value1</Property1>
<Property2>Value2</Property2>
</MyRequiredRoot>
</MyXML>
</_x0040_MyTableVar>
The code below can be run as is...
DECLARE #MyDesiredXMLOut XML;
DECLARE #MyActualXMLOut XML;
SELECT #MyDesiredXMLOut =
CONVERT( XML,
'<MyRequiredRoot><Property1>Value1</Property1>
<Property2>Value2</Property2>
</MyRequiredRoot>' );
DECLARE #MyTableVar table( ID int NOT NULL, MyXML XML NOT NULL );
INSERT INTO #MyTableVar VALUES( 1, #MyDesiredXMLOut )
SELECT #MyActualXMLOut =
( SELECT MyXML
FROM #MyTableVar
WHERE ID = 1
FOR XML AUTO )
SELECT #MyDesiredXMLOut;
SELECT #MyActualXMLOut;
FOR XML AUTO is trying to add information about your table name (which likely contains characters that aren't valid XML element names) and the column name it came from.
Change
SELECT #MyActualXMLOut =
( SELECT MyXML
FROM #MyTableVar
WHERE ID = 1
FOR XML AUTO )
to
SELECT #MyActualXMLOut =
( SELECT MyXML as '*'
FROM #MyTableVar
WHERE ID = 1
FOR XML PATH('') )
Explanation: as '*' tells SQL Server that you just want the column value directly, don't use the column name as a tag name; FOR XML PATH('') says you don't want to add any additional root node around the output, just use as is.
You can use query('/')
SELECT #MyActualXMLOut =
( SELECT MyXML.query ('/')
FROM #MyTableVar
WHERE ID = 1
FOR XML PATH('')
)
I don't know if this is real life example, but:
The value in the table is the XML already...
Leave away the FOR XML AUTO (Anyway as pointed out one should prefer PATH):
SELECT #MyActualXMLOut =
( SELECT MyXML
FROM #MyTableVar
WHERE ID = 1);
Or even simpler
SELECT #MyActualXMLOut = MyXML
FROM #MyTableVar
WHERE ID = 1;

Get updated row as XML

Is there any way to get the last updated row as XML in sql server?
Consider this snippet
DECLARE #table TABLE (
NAME NVARCHAR(255)
,Col2 INT
)
INSERT INTO #table
VALUES (
'a1'
,1
)
INSERT INTO #table
VALUES (
'a2'
,2
)
UPDATE #table
SET NAME = 'hello'
OUTPUT inserted.*
WHERE Col2 = 2
The above statements outputs the updated row. How can I output the row as XML, as I would do with a SELECT statement?
I tried the SELECT syntax, but was unsuccessful.
UPDATE #table
SET NAME = 'hello'
OUTPUT (inserted.* FOR XML AUTO)
WHERE Col2 = 2
Is there any way to accomplish this other than writing it to a table and selecting from the table?
Is there any way to accomplish this other than writing it to a table
and selecting from the table?
Not that I know of. Create a table variable where you insert the output from the update and then use that to create the XML output you want.
DECLARE #table TABLE
(
NAME NVARCHAR(255),
Col2 INT
);
INSERT INTO #table VALUES ('a1', 1);
INSERT INTO #table VALUES ('a2', 2);
DECLARE #updateresult TABLE
(
NAME NVARCHAR(255),
Col2 INT
);
UPDATE #table
SET NAME = 'hello'
OUTPUT inserted.NAME,
inserted.Col2
INTO #updateresult(Name, Col2)
WHERE Col2 = 2
SELECT NAME, Col2
FROM #updateresult
FOR XML PATH('row');

SQL Server Scalar variable in Inline table valued function

I have a multi statement table valued function which I would like to change to an inline table valued function for optimization purposes ( I don't really know if that will be an optimization but I want to try that anyway ). My problem is that I have a scalar variable which I don't know how to put in my WITH statement.
Code example:
CREATE FUNCTION [dbo].[function]()
RETURNS
#return_table table (id INT,value NVARCHAR(500))
AS
BEGIN
DECLARE #tmp_table TABLE(id INT, value VARCHAR(500))
DECLARE #variable BIGINT
INSERT INTO #tmp_table [...insert code...]
SET #variable = (SELECT MAX(id) FROM #tmp_table)
INSERT INTO #return_table SELECT id,value FROM #tmp_table WHERE id = #variable
RETURN
This code is an example, the actual function is more complex but the problem is exactly the same
I could easily change this to a single WITH statement like this:
CREATE FUNCTION [dbo].[function]()
RETURNS TABLE
AS
RETURN
(
WITH tmp_table AS (
SELECT [...Select Code...]
)
SELECT id,value FROM tmp_table
WHERE id = [variable]
);
GO
My problem lies into the [variable] which I don't know how to put into the query. Also, the variable is used more than once in my function so I'd rather not just replace it with the query.
I also tried this approach:
CREATE FUNCTION [dbo].[function]()
RETURNS TABLE
AS
RETURN
(
WITH tmp_table AS (
SELECT [...Select Code...]
), variable = (SELECT MAX(id) value FROM tmp_table)
SELECT id,value FROM tmp_table
WHERE id = (SELECT TOP 1 value FROM variable)
);
GO
But is seems like it made the function way slower.
Thank you.
Just try
WITH tmp_table AS (
SELECT [...Select Code...]
)
SELECT id,value FROM tmp_table WHERE id = (SELECT MAX(id) FROM tmp_table)
I would actually just change it to
SELECT TOP 1 *
FROm [whatever]
ORDER BY id DESC

contains search over a table variable or a temp table

i'm trying to concatenate several columns from a persistent table into one column of a table variable, so that i can run a contains("foo" and "bar") and get a result even if foo is not in the same column as bar.
however, it isn't possible to create a unique index on a table variable, hence no fulltext index to run a contains.
is there a way to, dynamically, concatenate several columns and run a contains on them? here's an example:
declare #t0 table
(
id uniqueidentifier not null,
search_text varchar(max)
)
declare #t1 table ( id uniqueidentifier )
insert into
#t0 (id, search_text)
select
id,
foo + bar
from
description_table
insert into
#t1
select
id
from
#t0
where
contains( search_text, '"c++*" AND "programming*"' )
You cannot use CONTAINS on a table that has not been configured to use Full Text Indexing, and that cannot be applied to table variables.
If you want to use CONTAINS (as opposed to the less flexible PATINDEX) you will need to base the whole query on a table with a FT index.
You can't use full text indexing on a table variable but you can apply the full text parser. Would something like this do what you need?
declare #d table
(
id int identity(1,1),
testing varchar(1000)
)
INSERT INTO #D VALUES ('c++ programming')
INSERT INTO #D VALUES ('c# programming')
INSERT INTO #D VALUES ('c++ books')
SELECT id
FROM #D
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(testing,'"','""') + '"', 1033, 0,0)
where display_term in ('c++','programming')
GROUP BY id
HAVING COUNT(DISTINCT display_term)=2
NB: There might well be a better way of using the parser but I couldn't quite figure it out. Details of it are at this link
declare #table table
(
id int,
fname varchar(50)
)
insert into #table select 1, 'Adam James Will'
insert into #table select 1, 'Jain William'
insert into #table select 1, 'Bob Rob James'
select * from #table where fname like '%ja%' and fname like '%wi%'
Is it something like this.

Resources