How use the insert query using parameters? - sql

When i try with this query i get an error says that Perameter email doesn't exist, i am sure that the variables : email, login_pass, payment_method,operateur are valid and exists.
SQLQuery2.sql.Text := 'INSERT INTO registered (email,login_pass,payment_method,operateur) VALUES (":email",":login_pass",":payment_method",":avecpuce")';
SQLQuery2.ParamByName('email').AsString := email;
SQLQuery2.ParamByName('login_pass').AsString := login_pass;
SQLQuery2.ParamByName('payment_method').AsString := payment_method;
SQLQuery2.ParamByName('avecpuce').AsString := avecpuce;
SQLQuery2.ExecSQL(true);
I tried removing the quotation, but i get
You have an error in your Sql syntax, check the manual that corresponds to your SQL server for the right syntax to use near
':email,:login_pass,:payment_method,:avecpuce)' at line 1
How to use the insert query above using parameters?

From the TSQLQuery.ExecSQL documentation:
ExecDirect indicates that the query does not need to be prepared
before it is executed. This parameter can be set to true if the query
does not include any parameters.
So if the code uses
SQLQuery2.ExecSQL(true);
this means that there will be no support for parameters.
But because you use parameters, just use
SQLQuery2.ExecSQL;
and also remove the quotes around parameters.

Remove quotation marks:
SQLQuery2.sql.Text := 'INSERT INTO registered (email,login_pass,payment_method,operateur)
VALUES (:email, :login_pass, :payment_method, :avecpuce)';

Found the answer !
MySQLQuery2.SQL.Clear;
MySQLQuery2.SQL.Add('INSERT INTO COUNTRY (NAME, CAPITAL, POPULATION)');
MySQLQuery2.SQL.Add('VALUES (:Name, :Capital, :Population)');
MySQLQuery2.Params[0].AsString := 'Lichtenstein';
MySQLQuery2.Params[1].AsString := 'Vaduz';
MySQLQuery2.Params[2].AsInteger := 420000;
MySQLQuery2.ExecSQL;
Thankyou All !!

You don't usually quote parameters, only literals. So instead of:
VALUES (":email",":login_pass",":payment_method",":avecpuce")
Try:
VALUES (:email,:login_pass,:payment_method,:avecpuce)

You should not use quotes around the parameter name.
Parameters are automatically generated for you if your TSQLQuery has a connection assigned and ParamCheck is true and you assign TSQLQuery.CommandText.
It will not generate the parameters when you assign the query to TSQLQuery.SQL.Text.
You can have the parameters generated for you by calling TSQLQuery.Params.ParseSQL:
SQLQuery2.Params.ParseSQL(SQLQuery2.SQL.Text, True);
Or you can add them yourself by calling TSQLQuery.Params.AddParameter.

Related

How correctly pass arguments to the SQL request via the sqlx package in Golang?

In my Golang (1.15) application I use sqlx package to work with the PostgreSQL database (PostgreSQL 12.5).
When I try to execute SQL statement with arguments PostgreSQL database it raises an error:
ERROR: could not determine data type of parameter $1 (SQLSTATE 42P18):
PgError null
According to the official documentation, this error means that an INDETERMINATE DATATYPE was passed.
The organizationId has value. It's not null/nil or empty. Also, its data type is a simple built-in data type *string.
Code snippet with Query method:
rows, err := cr.db.Query(`
select
channels.channel_id::text,
channels.channel_name::text
from
channels
left join organizations on
channels.organization_id = organizations.organization_id
where
organizations.tree_organization_id like concat( '%', '\', $1, '%' );`, *organizationId)
if err != nil {
fmt.Println(err)
}
I also tried to use NamedQuery but it also raise error:
ERROR: syntax error at or near ":" (SQLSTATE 42601): PgError null
Code snippet with NamedQuery method:
args := map[string]interface{}{"organization_id": *organizationId}
rows, err := cr.db.NamedQuery(`
select
channels.channel_id::text,
channels.channel_name::text
from
channels
left join organizations on
channels.organization_id = organizations.organization_id
where
organizations.tree_organization_id like concat( '%', '\', :organization_id, '%' );`, args)
if err != nil {
fmt.Println(err)
}
In all likelihood, the arguments is not passed correctly to my request. Can someone explain how to fix this strange behavior?
P.S. I must say right away that I do not want to form an sql query through concatenation, or through the fmt.Sprintf method. It's not safe.
Well, I found the solution of this problem.
I found the discussion in github repository of the sqlx package.
In the first option, we can make concatenation of our search string outside of the query. This should still be safe from injection attacks.
The second choice to try this: concat( '%', '\', $1::text, '%' ). As Bjarni Ragnarsson said in the comment, PostgreSQL cannot deduce the type of $1.

How to prevent SQL Injection in PL/SQL

We have some few packages where we need to resolve some SQL Injection issues. I need some help to rewrite sql statement or sanitize the inputs. Below is the line number where veracode throw the error.
open c_ccl (p_part_nr,p_ctry_cd);
// Source code
CREATE OR REPLACE EDITIONABLE PACKAGE BODY "schema"."Test_PKG" AS
v_data t_cla_class_data;
FUNCTION nat_eccn_cd( p_part_nr IN t_part_nr, p_ctry_cd IN t_ctry_cd )
RETURN t_us_eccn_cd IS
CURSOR c_ccl(p_part_nr CHAR, p_ctry_cd CHAR) IS
SELECT NAT_CCL_CD FROM CLSDBA.CLA_EXP_PART_CTRY e
WHERE e.PART_NR = p_part_nr AND e.CTRY_CD = p_ctry_cd
ORDER BY e.VAL_FROM_DT DESC;
v_ctry_cd char(4) := p_ctry_cd;
v_trf_cd char(4);
BEGIN
v_data.nat_eccn_cd := NULL;
open c_ccl (p_part_nr,p_ctry_cd);
fetch c_ccl INTO v_data.nat_eccn_cd;
close c_ccl;
return (trim(v_data.nat_eccn_cd));
exception when others then return NULL;
end;
I don't see any SQL injection issues with your code - there is no dynamic code where the user inputs could be evaluated and escape out of the expected code flow. Unless your code snippet is generated somewhere else, or one of the column names is really a function that calls dynamic SQL, your code looks safe.
You used the phrase "sanitize the inputs", which is terrible advice for database programming. As much as I love the comic strip XKCD, Randall got this one wrong.
Bind variables are the best solution to avoiding SQL injection. I'll take this opportunity to (poorly) change his comic:

Drupal 7 - db_select: SQL function in where condition

I need to use this condition in my select statement:
WHERE YEAR(date) = YEAR(CURDATE())
but if I do, like this:
$query = db_select('table', 't');
$query->fields('t');
$query->condition('YEAR\(date\)', 'YEAR(CURDATE())', '=');
Drupal won't have it (even if I do not escape those parenthesis - it simply ignores them) because I get an error:
Column not found: 1054 Unknown column 'YEARdate' in 'where clause':
How to overcome this error?
Hmm.. just like this, it seems:
$query->where('YEAR(date) = YEAR(CURDATE())');
The where allows for the arbitrary SQL:
The where() method allows for the addition of arbitrary SQL as a conditional fragment. $snippet may contain any legal SQL fragment, and if it has variable content it must be added using a named placeholder. The $args array is an array of placeholders and values that will be substituted into the snippet. It is up to the developer to ensure that the snippet is valid SQL. No database-specific modifications are made to the snippet.
Hm, you could also use db_query, it allow you to write SQL queries "without Drupal".
I mean, you'll be able to add custom WHERE statements or any SQL-proper functions, like custom functions ;)
Eg.
$result = db_query('SELECT title FROM {node} WHERE type = "%s" AND title LIKE "%%%s%%"', 'type', 'title');
Use addExpression method :
https://api.drupal.org/api/drupal/includes!database!select.inc/function/SelectQuery%3A%3AaddExpression/7.x
$query = db_select('table', 't');
$query->fields('t');
$query->addExpression('YEAR(t.date) = YEAR(CURDATE())');
$result = $query->execute()->fetchAll();
var_dump($result);

DB2 PL/SQL structure, begin atomic including with query

I'm trying to use db2 pl/sql script giving a template code.
--#set delimiter !
begin atomic
for S as
<query statement that finds quests, "swaps", with a donor/donation & recipient pair>
do
<update statement that fixes Loot with the swap 'S'>;
end for;
-- handle each swap
end!
-- we're done once through
in my query statement i used something like this:
with
t1 (args) as (
...
)
...
select ...
where ... ;
in the update statement
update Loot set ... where ...
but the problem is, when i try to run the full sql code script on the database, I keep getting the message :
"An unexpected token "begin" was found following "<identifier>".
Expected tokens may include: "USER". SQLSTATE=42601 DB21007E End of file
reached while reading the command.
I want to know, how to use the proper syntax or format to include the "with queries" and also update statement to stop giving me the error. I have the "with query" working in a separate file, but when i combine both statements into the template, it would give me this error. Also as well, if I were to include triggers, which part of the code should i put it in. Thank you.
Here is an example that might help.
CREATE TABLE EG(I INT, J INT)!
INSERT INTO EG VALUES (1,1),(2,3)!
begin
for c as with w(i,u) as(values (2,5)) select i,u from w
do
update eg set j = j + c.u where i = c.i;
end for;
end
!
If this does not help your problem, please post a version of your code that we can run and which returns the error message that you are struggling with.

Fitnesse and dbFit: how to escape colons in SQL queries

I've a problem with escaping colons and dashes in SQL queries when I use dbFit with Fitnesse.
Such statement doesn't work:
!|Query|select to_char(my_birthday,'YYYY-MM-DD HH24:MI:SI') from family|
I need to replace colons and dashes with some other acceptable characters, ex.
!|Query|select to_char(my_birthday,'YYYY_MM_DD HH24_MI_SI') from family|
Do you know how to solve it properly without using the 2nd approach ?
Cheers,
foxrafi
I think this is what you need. From http://dbfit.github.io/dbfit/docs/reference.html
Avoiding parameter mapping
If you want to prevent DbFit from mapping parameters to bind variables
(eg to execute a stored procedure definition that contains the #
symbol in Sql Server), disable bind symbols option before running the
query.
|set option|bind symbols|false|
|execute| insert into users (name, username) values ('#hey','uuu')|
|query|select * from users| |name|username| |#hey|uuu|
Remember to re-enable the option after the query is executed. You can
use the same trick with the Execute command.
In addition to Mike's answer, you can also solve this by using bind parameters. This is useful if you have to use bind parameters at other places in the same query.
!|DatabaseEnvironment|ORACLE|
|Connect|${HOSTNAME}|${USERNAME}|${PASSWORD}|
!|Query|!-select current_timestamp ts from dual-!|
|ts?|
|>>my_birthday_ts|
|set parameter|my_birthday_ts| <<my_birthday_ts|
#Set bind parameter :MI to string ':MI'
|set parameter|MI|:MI|
# and do it in the same way with :SS.
|set parameter|SS|:SS|
!|Query|!-select to_char(:my_birthday_ts, 'YYYY-MM-DD HH24'|| :MI || :SS) bds from dual-!|
|bds?|
|>>birthday_string|
Note that you have to use !- -! around your query, otherwise FitNesse will expand the concatenation operator to table cells. The main drawback of this manner is that you cannot use ordinary FitNesse variables (${varname}) in the query.
!|DatabaseEnvironment|ORACLE|
|Connect|${HOSTNAME}|${USERNAME}|${PASSWORD}|
!|Query|!-select current_timestamp ts from dual-!|
|ts?|
|>>my_birthday_ts|
!|Query|!-select to_char(:my_birthday_ts, 'YYYY-MM-DD HH24:'||'MI:'||'SS) bds from dual-!|
|bds?|
|>>birthday_string|