' on a procedure/function - sql

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.

Related

How to dynamically format BigQuery `dataset.schema.table name` with backticks

I need to work through how to take stored procedure functions from
region-us.INFORMATION_SCHEMA.ROUTINES
and modify the backticks that default to coming through around the project and place them around the dataset.schema.table()
The reason is more for uniform results across our system than a technical error need.
currently when I run this query
SELECT
replace(ddl, 'CREATE PROC', 'CREATE OR REPLACE PROC'),
FROM region-us.INFORMATION_SCHEMA.ROUTINES
where lower(routine_type) = 'procedure'
It will return the below:
`project-data-sandbox`.schema.MySP()
`project-data-sandbox`.schema.YourSP(MySP)
`project-data-sandbox`.inv.partnumber(orderid)
`project-data-sandbox`.inv_part.part_number(part_id)
I have tried the below query
SELECT
REGEXP_REPLACE(ddl, r"project-data-sandbox`.", "project-data-sandbox.") AS replaced_word
, REGEXP_REPLACE(ddl, r'`([a-zA-Z]+(-[a-zA-Z]+)+)`\.[a-zA-Z]+\.[a-zA-Z]+\(\)','Apples') tester
FROM region-us.INFORMATION_SCHEMA.ROUTINES
where lower(routine_type) = 'procedure'
I get part of what I want. However, the problem is our stored procedures can be named any sort of names and they could require objects to be passed to them.
I added the tester column to see if I could replace the project string with another word (or regex) but it isn't even replacing it with apples yet.
which I would want turned into this:
`project-data-sandbox.schema.MySP`()
`project-data-sandbox.schema.YourSP`(MySP)
`project-data-sandbox.inv.partnumber`(orderid)
`project-data-sandbox.inv_part.part_number`(part_id)
I'm working through Regexp_replace but I'm having difficulty figuring out how to get the backtick between the parenthesis and the last letter.
Thanks for any help!

SSIS: How do I pass string parameter in an update statement in Execute SQL Task?

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 = ?

How to create correct SQL statement in delphi

I am pretty new to delphi and I would like to ask how can I create a correct SQL statement / SQL string in delphi.
I have tried something like this:
sql:='use [TestovaciaDb] INSERT INTO [dbo].[client]([Meno],[Priezvisko]) VALUES('+name+','+surname+')';
I am using MS SQL server 2012
But I am getting a exception there. Thank you
EDIT:
meno and priez are variables with values from TEdit1 and TEdit2:
meno:= Edit1.Text;
priez:= Edit2.Text;
Use parameterized queries. You set the database in your ConnectionString, so you don't need to `use' it in your query.
ADOQuery1.SQL.Text := 'INSERT INTO [dbo].[client] ([Meno],[Priezvisko]) ' +
'VALUES(:Meno, :Priezvisko)';
ADOQuery1.Parameters.ParamByName('Meno').Value := Edit1.Text;
ADOQuery1.Parameters.ParamByName('Priezvisko').Value := Edit2.Text;
ADOQuery1.ExecSQL;
Remove the use [xxx] at the begining of the statement. The connection you use must be already configured to point to the correct database. Just like many others said, avoid creating your sentences by using constants, instead, use paramenters.
http://docwiki.embarcadero.com/Libraries/XE3/en/System.SysUtils.QuotedStr
Use QuotedStr function.
For example
sql:='use [TestovaciaDb] INSERT INTO [dbo].[client]([Meno],[Priezvisko]) VALUES('+QuotedStr(name)+','+QuotedStr(surname)+')';
Use QuotedStr to convert the string S to a quoted string. A single quotation mark (') is inserted at the beginning and end of S, and each single quotation mark in the string is repeated. To remove the quotation marks from a quoted string, use the AnsiDequotedStr routine.

What does 'colon' mean in SQL under WHERE clause?

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.

How to escape special characters like " in the SQL query in order to avoid Injection

Using delphi 2010, i am wondering if there someway to escape the following string to make it safe from sql injection attacks :
my string :
SQLQuery1.SQL.Text := 'SELECT * FROM registered WHERE email="'+
email+'" and login_pass="'+password+'"';
How to rewrite this string, to make it safer than it is when someone type " in my TEditbox as his email or password !
Use parameters, and let the database drivers handle that stuff.
SQLQuery1.SQL.Text := 'SELECT * FROM registered WHERE email= :email'+
' and login_pass = :password';
SQLQuery1.ParamByName('email').AsString := EMail;
SQLQuery1.ParamByName('password').AsString := Password;
the basic replacement of ' with '' should make sure that you won't get injected in textual fields.
As a rule of thumb, make sure all inputs you add to the database are in the pattern you expect them to be.
in the case of email addresses, zip codes and passwords- you can define a simple regex to verify the validity.
keep in mind, that numeric fields can be also injected and should be verified as well.
If for whatever reason you can't use parameters, you can use a function like this:
USES SysUtils;
FUNCTION QuotedStr(CONST S : STRING) : STRING;
BEGIN
Result:='"'+ReplaceStr(S,'"','""')+'"'
END;
and then
SQLQuery1.SQL.Text := 'SELECT * FROM registered WHERE email='+
QuotedStr(email)+' and login_pass='+QuotedStr(password);
(this assumes that your database provider uses double quotes to delimit strings with and that two consecutive double quotes in a quoted string is really a single double quote, ie. one double quote).