I have SQL function, it is not written by me.
I am having hard time understanding, what does following condition mean?
specifically :key and ||cLF||'.
WHERE ' WHERE 1=1 '
||cLF||' AND f.key = :key '
||cLF||' AND i.flag = 0'
||cLF||' AND r.flag = 0'
First, the || operator is a string concatenation operator. So it looks like the code is building a WHERE clause using conditions specified by cLF. Though I'm not entirely sure why they're tacking on cLF three times there.
The :key syntax refers to a parameter in a parameterized query. Its value will be passed in when the SQL statement you're building is actually run.
The query you have pasted is a part of a dynamically constructed SQL statement.
Semicolon here points to a bind-place holder, meaning that the actual value for ":key" is passed through an argument and not hard coded.
Read examples on EXECUTE IMMEDIATE.
Related
I am working on an MS Access to SQL Server Migration project and am currently in the process of converting a complex query into T-SQL from MS Access.
Now I'm quite familiar with how Nz works in Access and how a 0 or empty string " " is returned if the valueifnull argument is not provided.
Source: https://support.office.com/en-gb/article/nz-function-8ef85549-cc9c-438b-860a-7fd9f4c69b6c
The exception to this rule is if the Nz function is used within a query expression, in which case, the returned value in the event of a null in the Variant, is an empty string.
Now, moving onto my actual problem, I am working on converting this Nz-filled query expression into T-SQL using ISNULL in T-SQL.
ISNULL requires 2 arguments. Both the Expression and the Value. The latter being an optional argument in Access' Nz, has made it a bit difficult for me to translate the expression. The Value argument also needs to match the original data type of the Variant (in SQL Server), this means that I can not just simply add an empty string " " as the second argument as Nz in Access does by default.
Take a snippet of the complex query I use in Access compared to what I've written in T-SQL:
Access
TotalWIP: IIf([PercentageDoneTotal]<0,0,IIf(nz([TotalPurchasesReceived])+
(IIf([PercentageDoneTotal]>0,nz([TotalStockAllocated]),0))+IIf((([Accepted
Price]*[OutstandingBalance]*0.9)-nz([TotalPurchasesReceived])-
(IIf([PercentageDoneTotal]>0,nz([TotalStockAllocated]),0)))>0,((([Accepted
Price]*[OutstandingBalance]*0.9)-nz([TotalPurchasesReceived])-
(IIf([PercentageDoneTotal]>0,nz([TotalStockAllocated]),0)))*
[PercentageDoneTotal]),0)>([Accepted Price]*[OutstandingBalance]*0.9),
([Accepted Price]*[OutstandingBalance]*0.9),nz([TotalPurchasesReceived])+
(IIf([PercentageDoneTotal]>0,nz([TotalStockAllocated]),0))+IIf((([Accepted
Price]*[OutstandingBalance]*0.9)-nz([TotalPurchasesReceived])-
(IIf([PercentageDoneTotal]>0,nz([TotalStockAllocated]),0)))>0,((([Accepted
Price]*[OutstandingBalance]*0.9)-nz([TotalPurchasesReceived])-
(IIf([PercentageDoneTotal]>0,nz([TotalStockAllocated]),0)))*
[PercentageDoneTotal]),0)))
T-SQL
IIf([PercentageDoneTotal]<0,0,
IIf(ISNULL([TotalPurchasesReceived],NULL)+
(IIf([PercentageDoneTotal]>0,ISNULL([TotalStockAllocated],NULL),0))+
IIf((([Accepted Price]*[OutstandingBalance]*0.9)-
ISNULL([TotalPurchasesReceived],NULL)
-(IIf([PercentageDoneTotal]>0,ISNULL([TotalStockAllocated],NULL),0)))>0,
((([Accepted Price]*[OutstandingBalance]*0.9)-
ISNULL([TotalPurchasesReceived],NULL)-
(IIf([PercentageDoneTotal]>0,ISNULL([TotalStockAllocated],NULL),0)))*
[PercentageDoneTotal]),0)>([Accepted Price]*[OutstandingBalance]*0.9),
([Accepted Price]*
[OutstandingBalance]*0.9),ISNULL([TotalPurchasesReceived],NULL)+
(IIf([PercentageDoneTotal]>0,ISNULL([TotalStockAllocated],NULL),0))+
IIf((([Accepted Price]*[OutstandingBalance]*0.9)-
ISNULL([TotalPurchasesReceived],NULL)-
(IIf([PercentageDoneTotal]>0,ISNULL([TotalStockAllocated],NULL),0)))>0,
((([Accepted Price]*[OutstandingBalance]*0.9)-
ISNULL([TotalPurchasesReceived],NULL)-
(IIf([PercentageDoneTotal]>0,ISNULL([TotalStockAllocated],NULL),0)))*
[PercentageDoneTotal]),0))
) AS TotalWIP
Note the above NULL in the T-SQL example. This NULL is not suitable as it is messing up my calculations, I essentially need to mimic Nz without a second argument in T-SQL.
Edit:
Without putting the entire query into this question, Here is an expected result for Job Number: 294784 in both MS Access and SQL Server:
Access Results:
SQL Results:
Edit 2: have added the edited to add entire code.
As #Salman A noted, this is a great reason not to use variant. But having said that, I assume that you are looking for a numeric value, so why not use:
IIF([PercentageDoneTotal]<0,0, IIF(ISNULL([TotalPurchasesReceived],0)+
(IIF([PercentageDoneTotal]>0,ISNULL([TotalStockAllocate],0),0))
I dont know when put '.
For example on a procedure, When i write execute immediate 'sentence'
if there are one value in the sentenece i put
'||valor||'
but on a function i dont know why i had to write
return 'UPPER(USER_NAME) = ''' || user || '''';
not only '||user||'.
Anyone can help me?
Don`t construct your query with concatenated values.
Use something like that instead
EXECUTE IMMEDIATE 'SELECT user_id FROM user_table WHERE UPPER( username ) = :1' INTO your_user_id USING UPPER( your_user_name );
It will handle all cases. In your example, what will happen if user contains a ' ? What if you have 2 successive ' ? It can be a real nightmare to handle.
Here's some examples from Oracle
user is a string in SQL and should be quoted in the SQL query: Your final query, apart from any escaping, should read UPPER(USER_NAME) = 'user', not UPPER(USER_NAME) = user.
But the whole query fragment is a string in PL/SQL, so you have to put a string in a string. To get the quotes for the SQL string in the PL/SQL string, you need to double them to 'escape' them, so Oracle doesn't think that the PL/SQL string itself ends.
So when you write '''', the outer quote define the boundaries of the (PL/SQL) string itself, and the inner two quotes are a single escaped quote inside that string.
Anyway, while this may be the actual answer to your question, and definitely helpful if you would need an empty set of quotes or a fixed string in your query, in general it's way better to use parameterized queries, so I urge you to follow Luc M's example.
here whatever comes within two single quotes(') will be considered as string. but what if you needed a string with single quotes within itself.
example,
if you need a word - sample - for a variable, it can be simply declared as l_var := 'sample'.
but if the string is needed with single quotes like - 'It's sample'??
in this case if we let as it is, the sql engine will read from first single quote to next single quote,.. likewise...
in this case we will use single quotes multiple times as required.
it can be referred from below example:
declare
single_quote_string varchar2(20):= 'sample';
multi_quote_string varchar2(20):= 'It''s sample';
multi_quote2_string varchar2(20):= '''It''s sample''';
begin
dbms_output.put_line('single_quote_string:'||single_quote_string);
dbms_output.put_line('multi_quote_string:'||multi_quote_string);
dbms_output.put_line('multi_quote2_string:'||multi_quote2_string);
end;
--output
single_quote_string:sample
multi_quote_string:It's sample
multi_quote2_string:'It's sample'
in your question , you were asking about use of : return 'UPPER(USER_NAME) = ''' || user || ''''; in execute immediate statement.
execute immediate is used to execute a string.
in your case, it's the where condition of user name.
when having normal sql, we will be having
upper(username) = 'SAMPLE';
but here this condition has to be passed as string to execute immediate command, meaning the single quotes which we use normally must be passed as a string, and hence we using multiple times.
if still not clear, you can try to display the execute immediate statement that you using in your code, which will output the sql command that you trying to run in execute immediate command.
I have one execute SQL Task in SSIS 2012 which has update statement. I want to pass a string variable in the where clause of this update statement. The update section is as below:
where coalesce(s1.iteration, '') not like '%?%' and s2.Iteration = '?'
Here, ? needs to be replaced with a string variable, which in this case would be 08152017. I have added the variable to the Parameter Mapping. Screenshot is attached.
The task executes successfully but does not updates the value in the intended column. It seems the query is not passing the value.What am I doing wrong? How do I check that the SQL inside the Execute SQL Task is actually getting the value from the variable?
First of all, when you set your variable in parameter mapping, make sure the datatype is NVARCHAR and not LONG.
Second you need to write your statement like this:
where coalesce(s1.iteration, '') not like '%?%' and s2.Iteration = ?
You dont need '' because your variable is already set as a string.
Try to hardcode your value in your variable to see if it passes. Otherwise, set a breakpoint on pre-execute to see wheter your variable has a value.
If your variable has a value and your SQL is not working, maybe you should look into your SQL. Maybe try it directly in SSMS to see if it actually runs or does anything.
In scenario ? is Integer type variable, then please use below format:
SELECT ? +' Hello World!'
The above does not require the use of an additional string variable.
Create a user variable with % on it, for example, variable name is Like_Var with data type String
"%" + #Orig_Var + "%"
Let's say, Orig_Var has a value of 08152017, therefore Like_Var will have %08152017%
Then use Like_Var on your parameter in Execute SQL Task as parameter 0, data type VARCHAR in Parameter Mapping
WHERE COALESCE(s1.iteration, '') NOT LIKE ?
AND s2.Iteration = ?
IC=IC
ACC=ACC
v_statement='ACC = '1052502',0.035,IC = 'IC130',0.0675'
v_decode_out=DECODE(TRUE,v_statement,0)
i am getting error
is the above expression correct.Is there anyway we can achieve this
There are two problems in your query
First, the v_statement variable you have written won't be validated. If you
really want to write a string in this format, then use pipes to append as
'ACC='||1052502||','||0.035||'IC='||'IC130'||','||'0.0675'
Note that you cannot loop quotes.
Second, the reason your decode statement wont work is because of the data type mismatch. True is a boolean value and v_statement is a string. Any variable expansion would happen during run time but not before that. So, informatica does not allow you this kind of decode statement, unless you are comparing some kind of string input/variable with another string or any other data type for that matter
Also, decide on your case
When it is If ACC else IC to be evaluated (this seems to be your case)
v_decode_out=DECODE(ACC,'1052502',0.035,DECODE(IC,'IC130',0.0675))
When it is both ACC and IC together
v_decode_out=DECODE(TRUE,ACC='1052502' and/or IC='IC130',0.035,0.0675)
These are fundamental concepts. It's advisable that you try out everything available on internet before you post a question here, because someone could easily down rate you if they feel that you have not put any effort at all to find an answer yourself.
Cheers!
the v_statement variable you have written won't be validated. If you really want to write a string in this format, then use pipes to append.
I have come across the following example code:
EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
#profile_name = #'SQL mail profile',
#account_name = #'account name',
#sequence_number = 1 ;
What does '#' mean in front of the string literal, as in the example above:
#account_name=#'account name'
I understand that my question may stand true for any executable module's parameters in T-SQL, or maybe for any string literal in T-SQL in general, so the above is just a concrete example of what I'm looking at.
I do not think that this is valid T-SQL. This may be an artifact of replacing variables with values somewhere in a script and not trimming the leading #.
I get a syntax error with that, so I don't think it means anything except that it's not valid syntax. Did you pull that from valid T-SQL that is being called using just T-SQL, or perhaps this is parameterized stuff coming from some other language or program?