Sql Server pass variable to nodes function - sql

After I did some internet research I found out that nodes function for xml processing of Sql Server does not accept a variable as parameter. If I try to use a variable a get the following error:
The argument 1 of the XML data type method "nodes" must be a string literal.
This is what I am trying to do:
SET #xPath = REPLACE(#xPath,'|','/')
SET #xPath = '/' + #xPath + '/text()'
SELECT #ParsedHtml = #ParsedHtml + CONVERT(nvarchar(max),Col.query('.')) + ';' FROM #Html.nodes(#xPath)AS T(Col)
Is there any hack i can do to make nodes function accept a variable as parameter???

You can use a variable in the path like this:
SET #xPath = REPLACE(#xPath,'|','/')
set #ParsedHtml = ''
SELECT #ParsedHtml = #ParsedHtml + CONVERT(nvarchar(max),Col.query('.')) + ';'
FROM #Html.nodes('/*[local-name()=sql:variable("#xPath")]/text()')AS T(Col)
I don't think you can do multiple levels in one variable in the path, which it looks like you are trying to do. You'd have to specify each level with a parameter of it's own. If you need to do a dynamic number of path levels, you might look into using dynamic sql.

Related

Sql server column serialization without key

I have column A with value hello.
I need to migrate it into new column AJson with value ["hello"].
I have to do this with Sql Server command.
There are different commands FOR JSON etc. but they serialize value with column name.
This is the same value that C# method JsonConvert.SerializeObject(new List<string>(){"hello"} serialization result would be.
I can't simply attach [" in the beginning and end because the string value may contain characters which without proper serialization will break the json string.
My advice is you just make a lot of nested replaces and then do it yourself.
FOR JSON is intended for entire JSON, and therefore not valid without keys.
Here is a simple example that replaces the endline with \n
print replace('ab
c','
','\n')
Backspace to be replaced with \b.
Form feed to be replaced with \f.
Newline to be replaced with \n.
Carriage return to be replaced with \r.
Tab to be replaced with \t.
Double quote to be replaced with "
Backslash to be replaced with \
My approach was to use these 3 commands:
UPDATE Offers
SET [DetailsJson] =
(SELECT TOP 1 [Details] AS A
FROM Offers AS B
WHERE B.Id = Offers.Id
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
UPDATE Offers
SET [DetailsJson] = Substring([DetailsJson], 6, LEN([DetailsJson]) - 6)
UPDATE Offers
SET [DetailsJson] = '[' + [DetailsJson] + ']'
..for op's answer/table..
UPDATE Offers
SET [DetailsJson] = concat(N'["', string_escape([Details], 'json'), N'"]');
declare #col nvarchar(100) = N'
a b c " : [ ] ]
x
y
z'
select concat(N'["', string_escape(#col, 'json'), N'"]'), isjson(concat(N'["', string_escape(#col, 'json'), N'"]'));

Apply like function on an array is SQL Server

I am getting array from front end to perform filters according that inside the SQL query.
I want to apply a LIKE filter on the array. How to add an array inside LIKE function?
I am using Angular with Html as front end and Node as back end.
Array being passed in from the front end:
[ "Sports", "Life", "Relationship", ...]
SQL query is :
SELECT *
FROM Skills
WHERE Description LIKE ('%Sports%')
SELECT *
FROM Skills
WHERE Description LIKE ('%Life%')
SELECT *
FROM Skills
WHERE Description LIKE ('%Relationship%')
But I am getting an array from the front end - how to create a query for this?
In SQL Server 2017 you can use OPENJSON to consume the JSON string as-is:
SELECT *
FROM skills
WHERE EXISTS (
SELECT 1
FROM OPENJSON('["Sports", "Life", "Relationship"]', '$') AS j
WHERE skills.description LIKE '%' + j.value + '%'
)
Demo on db<>fiddle
As an example, for SQL Server 2016+ and STRING_SPLIT():
DECLARE #Str NVARCHAR(100) = N'mast;mode'
SELECT name FROM sys.databases sd
INNER JOIN STRING_SPLIT(#Str, N';') val ON sd.name LIKE N'%' + val.value + N'%'
-- returns:
name
------
master
model
Worth to mention that input data to be strictly controlled, since such way can lead to SQL Injection attack
As the alternative and more safer and simpler approach: SQL can be generated on an app side this way:
Select * from Skills
WHERE (
Description Like '%Sports%'
OR Description Like '%Life%'
OR Description Like '%Life%'
)
A simple map()-call on the words array will allow you to generate the corresponding queries, which you can then execute (with or without joining them first into a single string).
Demo:
var words = ["Sports", "Life", "Relationship"];
var template = "Select * From Skills Where Description Like ('%{0}%')";
var queries = words.map(word => template.replace('{0}', word));
var combinedQuery = queries.join("\r\n");
console.log(queries);
console.log(combinedQuery);

Execute SQL Task in SSIS string parameter

I created two string variables (tot and tot_value) and assigned a value (tot = MyVal) for testing. Then I created an Execute SQL Task which takes (tot) as parameter and the value returned is saved in tot_value.
In the General Tab, i set:
ResultSet to Single row. SQL Source Type to Direct input Query is listed below.
In Parameter Mapping I selected my tot variable with Input DirectionSQL_VARCHAR Data Type 1 as Parameter Name (Since i am using ODBC)Size set to default -1.
In Result SetResult Name to 1Variable Name to tot_value.
If in the query I hard code 'MyVal' i get the correct result, however when I use ? to use my variable as a parameter, I always get a 0 returned.
Note that my tot variable is set to MyVal
Any clue of what I might be missing? Thanks in advance
select TOP 1 CAST('' + ISNULL((SELECT distinct type_of_transfer_code
FROM SYSTEM.history_program_transfer
WHERE type_of_transfer_value = ?),'') AS VARCHAR(100)) as type_of_transfer_code
FROM SYSTEM.table_facility_defaults

SQL query with "as" keyword

I have a below SQL query running in one of my project. I am struggling to understand the "as" concept here. In the result "user_key" and "user_all" are appearing as empty. Where as at the front end "user_all" is the combination of "rx.ord_by_userid" + "rx.ord_by_inst_id,"
SELECT rx.rx_id,
rx.pt_visit_id,
rx.pt_id,
pt_visit.date_time_sch,
' ' as print_dea_ind,
' ' as phys_rx_label,
rx.ord_by_userid,
rx.ord_by_inst_id,
' ' as user_key,
pt_visit.visit_inst_id,
' ' as user_all,
' ' as tp_agt_ind,
FROM rx LEFT OUTER JOIN tx_pln ON rx.tp_name = tx_pln.tp_name AND rx.tp_vers_no = tx_pln.tp_vers_no, pt_visit
WHERE ( pt_visit.pt_visit_id = rx.pt_visit_id ) and
( pt_visit.pt_id = rx.pt_id ) and
( ( rx.pt_id = :pt_id ) and
( rx.rx_id = :rx_id ) )
Thanks.
I think when they query database, they need two fields called "user_key" and "user_all" with empty value for some purpose. However, in the front end, they need to display column "user_all" with the combination of "rx.ord_by_userid" + "rx.ord_by_inst_id" because of business rule.
The meaning of "AS" is just setting the alias of any field which is needed to have a new name. In this situation, new columns "user_key" and "user_all" are set with empty value.
AS just provides the field in the data set a name, or in SQL terms, an alias. In PB, this is usually done so that the DataWindow gives it a consistent, easy name. That is all that AS does.
The other part of your mystery is how these get populated with non-blank values. You were assuming this was done in the SQL with AS, but we can assure you that is not the case. Most likely, this value is being set in a script that fires in the client after the Retrieve() (if I were to bet, I'd bet a script on the DataWindow control, maybe RetrieveRow or RetrieveEnd).

PL/SQL: Using a variable in UPDATEXML function

I need to update an XML node that contains a specific number. My query works if I hard code in the number (see figure 1), but I would like to make this dynamic by passing through a variable that contains a string (variableToBeReplaced). I currently wrote this (see figure 2) but it isn't reading the variable correctly so no changes are being made to the xml. Does anyone know how I can include a variable in an updatexml() function?
Figure 1
select updateXML(xmltype(xmlbod),'/LpnList/Lpn/LicensePlateNumber[text() = "12345"]','67890').getClobVal() doc
from myTable
where id = '1'
Figure 2
select updateXML(xmltype(xmlbod), '/LpnList/Lpn/LicensePlateNumber[text()= '|| variableToBeReplaced || ']','67890').getClobVal() doc
from myTable
where id = '1'
I was just missing "" around the variable.
select updateXML(xmltype(xmlbod), '/LpnList/Lpn/LicensePlateNumber[text()= "'|| variableToBeReplaced || '"]','67890').getClobVal() doc
from myTable
where id = '1'