Sql Server 2012 How to Get List on Function - sql-server-2012

Function Details:
alter FUNCTION siralama_puan (#suggestion_id int)
RETURNS int
AS
Begin
Declare #comment_count int,#like_count int,#favorite_count int,#date_point int,#suggestion_point int,#suggestion_date datetime,#fark int
set #comment_count=(select [Suggestion].CommentCount from [Suggestion] where [Suggestion].Id= #suggestion_id)
set #like_count=(select [Suggestion].LikeCount from [Suggestion] where [Suggestion].Id=#suggestion_id)
set #favorite_count=(select [Suggestion].FavoriteCount from [Suggestion] where [Suggestion].Id=#suggestion_id)
set #suggestion_date=(select [Suggestion].Crtm from [Suggestion] where [Suggestion].Id=#suggestion_id)
set #fark =(select DATEDIFF(day,#suggestion_date,GETDATE()))
if #fark<6
set #date_point=30
else if #fark<10 and #fark>=6
set #date_point=20
else
set #date_point=10
set #suggestion_point=(#comment_count*2)+(#like_count)+(#favorite_count*3)+#date_point
RETURN #suggestion_point
End
Calling Function:
select dbo.siralama_puan (122280,1) as puan order by puan desc
but it didn't work.Error:Procedure or function dbo.siralama_puan has too many arguments specified.Multiple arguments not working.

It is not possible to define one parameter of type INT and pass in a list. But there are several approaches:
TYPE
Create your own type with CREATE TYPE read here.... This allows you to pass in a list very similar to a (read only) table
XML
Let your parameter be of type XML and pass in something like
<root>
<prm value="122280"/>
<prm value="1"/>
</root>
It's quite easy to transform this XML within your function to a list with something like
SELECT Prm.value('#value','int') AS PrmValue
FROM #prm.nodes('/root/prm') AS One(Prm)
CSV
A parameter of type VARCHAR(MAX) and a comma separated list like "122280,1". Find a way to split this here: section "Dynamic IN-statement"

Related

Logic for adding \ before every character in ADF parameter

I have a requirement in ADF wherein i have a parameter which can contain following values AB or A or B
I want to update these values by appending \ in front of each character.
So the output should be as follows:
For AB - \A\B
For A - \A
How to append \ in front of every character irrespective of number of characters in a parameter?
Please note that we don't want to use DataFlow for this.
You cannot do this with the native expressions in ADF. Either call an Azure function to perform the work, or use SQL and a Lookup Activity to perform the task. You can put the following into a dynamic expression referencing the following as an example;
declare ##str nvarchar(max) = 'helloworld'; /* get value in dynamic expression '#{#pipeline().parameters.PARAMETER_NAME}'*/
declare ##strOut nvarchar(max) = '';
declare ##strlen int = len(##str);
declare ##i int = 1;
while ##i <= ##strlen
begin
set ##strOut += concat('\',SUBSTRING(##str,##i,1));
set ##i +=1;
end
select ##strOut [result];
Then fetch the result from the activity. e.g. #activity('Lookup1').output.firstRow.result
As seen below, note the UI is just adding the extra \ in the preview, (ADF rendering bug)
The dynamic expression in the Lookup Query parameter :

Searching through XML in T-SQL with conditions

I am trying to get the correct info from an XML data type into regular scalar variables based on conditions, however I am having trouble getting the correct info back.
Here is the XML I am searching through:
<Loop2420>
<NM1>
<F98_1>PW</F98_1>
<F1065>2</F1065>
</NM1>
<N3>
<F166>81715 DOCTOR CARRE</F166>
</N3>
<N4>
<F19>INDIO</F19>
<F156>CA</F156>
<F116>92201</F116>
</N4>
</Loop2420>
<Loop2420>
<NM1>
<F98_1>45</F98_1>
<F1065>2</F1065>
</NM1>
<N3>
<F166>51250 MECCA AVE</F166>
</N3>
<N4>
<F19>COACHELLA</F19>
<F156>CA</F156>
<F116>92236</F116>
</N4>
</Loop2420>
Basically I need to get the numbers from <'F116'> but only if <'F98_1'> is equal to 'PW'.
I have tried:
declare #zip varchar(30)
select #zip = T.value('(F116)[1]','varchar(30)')
from #TransactionXML.nodes('/Loop2420/N4') Trans(T)
where T.value('(/Loop2420/NM1/F98_1)[1]','varchar(30)') = 'PW'
But that sometimes returns the value from <'F116'> even if <'F98_1'> is equal to '45'.
Any suggestions? Thanks.
Put the test in the XQuery itself and clamp it to the node you're checking:
SELECT #zip = T.value('(N4/F116)[1]', 'varchar(30)')
FROM #TransactionXML.nodes('/Loop2420') Trans(T)
WHERE T.exist('NM1/F98_1[text()="PW"]') = 1
If PW is not a static value, use the sql:variable() or sql:column() function to incorporate it in the query.

I want to extract columns from a single message column sql query

I have a logs message that I have to extract columns from with a sql query,
this how the message looks like:
"device=EOHCS-ZA-JIS-FW severity=high from=EOHCloudFAZ(FL1KVM0000005594) trigger=Syslog Critical System Alerts log="logver=54 itime=1528457940 devid=FG1K5D3I13800425 devname=FWJIS01 vd=95_LHC date=2018-06-08 time=13:34:55 logid=0100044546 type=event subtype=system level=information logdesc="Attribute configured" user="JoshuaK" ui="ha_daemon" action=Edit cfgtid=701760128 cfgpath="system.settings" cfgattr="gui-allow-unnamed-policy[disable->enable]" msg="Edit system.settings """
can someone give me an idea
I have a solution for SQL-Server, you could use PATINDEX and extract the log message.
Below is the code to extract from value
declare #input nVarchar(max),#from nVarchar(MAX)
declare #FromStart int,#FromEnd int
set #input='device=EOHCS-ZA-JIS-FW severity=high from=EOHCloudFAZ(FL1KVM0000005594) trigger=Syslog Critical System Alerts log="logver=54 itime=1528457940 devid=FG1K5D3I13800425 devname=FWJIS01 vd=95_LHC date=2018-06-08 time=13:34:55 logid=0100044546 type=event subtype=system level=information logdesc="Attribute configured" user="JoshuaK" ui="ha_daemon" action=Edit cfgtid=701760128 cfgpath="system.settings" cfgattr="gui-allow-unnamed-policy[disable->enable]" msg="Edit system.settings';
SET #FromStart=PATINDEX('%from=%',#input)+5;
SET #FromEnd=PATINDEX('% trigger=%',#input)-#FromStart;
SELECT #from=SUBSTRING(#input,#FromStart,#FromEnd)
SELECT #from
Note : use equivalent of PATINDEX for your corresponding DB server. Also note that this works only if the input string have parameters in a defined order.

Adding array to array with JSON_MODIFY

DECLARE #JSON_CurrentArray NVARCHAR(MAX) = '{"Some List":
[{"Name":"Item1","Id":"2"},{"Name":"Item2","Id":"3"}]}';
DECLARE #JSON_TopLevel NVARCHAR(MAX) = '{"OverAll":[{"Product Section":[]}]}';
SET #JSON_TopLevel = JSON_MODIFY(#JSON_TopLevel, 'append $."Overall"."Product Selection"', JSON_QUERY(#JSON_CurrentArray));
SELECT #JSON_TopLevel;
Ive been trying to stick CurrentArray into TopLevel,
Tried some crazy append/lax/strict combinations... but im new to JSON Manipulation and am almost at 'liquid brain stage' over this item.
I also thought about adding a blank array, but to no avail (i might be doing that wrong also)
Right now im code blind, so, If you can somehow inject one array into another... #foreverindebted.
If I understand you correctly you want something like this:
DECLARE #JSON_CurrentArray NVARCHAR(MAX) = '{"Some List":
[{"Name":"Item1","Id":"2"},{"Name":"Item2","Id":"3"}]}';
DECLARE #JSON_TopLevel NVARCHAR(MAX) = '{"OverAll":[{"Product Section":[]}]}';
SET #JSON_TopLevel = JSON_MODIFY(#JSON_TopLevel, 'append $."OverAll"[0]."Product Section"', JSON_QUERY(#JSON_CurrentArray));
SELECT #JSON_TopLevel;
DBFiddle
Result:
{"OverAll":[{"Product Section":[{"Some List": [{"Name":"Item1","Id":"2"},{"Name":"Item2","Id":"3"}]}]}]}
To check if your path is correct you could use JSON_QUERY and strict mode:
SELECT JSON_QUERY(#JSON_TopLevel, 'strict $."OverAll"."Product Section"')
--Msg 13608 Level 16 State 5 Line 7
--Property cannot be found on the specified JSON path.
-- vs
SELECT JSON_QUERY(#JSON_TopLevel, 'strict $."OverAll"[0]."Product Section"')
-- []

SQL, Find node value in xml variable, if it exists insert additional nodes into xml variable

I've got a Stored Procedure in SQL, where I have the following declaration:
Declare #fields xml
My SP gets passed values from the front end and then gets executed. The values it gets passed looks like this depending on what the user selects from the front end. For the purpose of this example I have included only 3 ID's.
'<F><ID>979</ID><ID>1000</ID><ID>989</ID></F>'
My question is this:
How can I find the node = 1000 and if that is present (exists) then insert (add) to 2 additional nodes,
<ID>992</ID><ID>993</ID>
to my existing '<F><ID>979</ID><ID>1000</ID><ID>989</ID></F>' xml.
If <ID>1000</ID> isn't present do nothing.
So, end result should be something like this if 1000 is present.
<F><ID>979</ID><ID>1000</ID><ID>989</ID><ID>992</ID><ID>993</ID></F>
If not, the result should stay:
<F><ID>979</ID><ID>1000</ID><ID>989</ID></F>
I just can't get my head around this?
Check this:
declare #fields xml = '<F><ID>979</ID><ID>1000</ID><ID>989</ID></F>'
, #add xml = '<ID>992</ID><ID>993</ID>'
;
if #fields.exist('/F[1]/ID[text()="1000"]') = 1
set #fields.modify('insert sql:variable("#add") as last into /F[1]');
select #fields