How to use prepare_statement with OCI Python SDK and NoSQL cloud service? - oracle-nosql

I am planning to use Oracle NoSQL Cloud Service on OCI using the OCI Python SDK. I did some tests using the API calls and I would like to do the same query but using the Python SDK.
How can I use prepared statement instead of regular statement (see below) and what values I need to set
print("second attempt")
table_name = 'table1'
statement = 'declare $id integer; select * from ' + table_name + ' where id=$id'
id_value = '1'
#nosqlClient.prepare_statement(compartment_id=comp_ocid,statement=statement),
query_response = nosqlClient.query(
query_details=oci.nosql.models.QueryDetails(
compartment_id=comp_ocid,
statement=statement,
is_prepared=True,
consistency="EVENTUAL",
variables={
'$id': id_value}))# Get the data from response
print(query_response.data)
Currently I have the following error :
oci.exceptions.ServiceError:
{'opc-request-id': '94E0B7EA0C864B379D66ED1C5215652A',
'code': 'InvalidParameter',
'message': 'QUERY: Illegal Argument: Deserialize prep query failed: Hash provided for prepared query does not match payload', 'status': 400}

the problem is with the "statement" attribute of QueryDetails.
use the result of the nosqlClient.prepare_statement (take care with the comma at the end in your script)
call oci.nosql.models.QueryDetails with the following parameters statement=prepare_statement_response.data.statement, is_prepared=True and variables
table_name = 'table1'
statement = 'declare $Id long; select * from ' + table_name + ' where id = $Id'
id_value = 1
prepare_statement_response = nosqlClient.prepare_statement(compartment_id=comp_ocid,statement=statement)
print(prepare_statement_response.data.statement)
query_response = nosqlClient.query(
query_details=oci.nosql.models.QueryDetails(
compartment_id=comp_ocid,
statement=prepare_statement_response.data.statement,
is_prepared=True,
consistency="EVENTUAL",
variables={
'$Id': id_value}))
print(query_response.data)
Hope that this can help you

Related

SSIS sending query with data parameter to Oracle cloud VS-2019 and MS Oracle Source

Already checked this post: SSIS and sending query with date to Oracle
And I'm using variable query per below thread
SSIS - Using parameters in Oracle Query using Attunity Oracle Datasource
Tool used: VS-2019
Data flow: MS Oracle Source (for VS-2019)
My source is Snowflake cloud. I'm successfully able to get the max date from table and store in Object type variable (named:- #var_Snowflake_Table_maxDate). Then I use a script task to convert the value to string type.
Code for script task is:
public void Main()
{
OleDbDataAdapter A = new OleDbDataAdapter(); //using System.Data.OleDb; ADDED above in NAMESPACES
System.Data.DataTable dt = new System.Data.DataTable();
A.Fill(dt, Dts.Variables["User::var_Snowflake_Table_maxDate"].Value);
foreach (DataRow row in dt.Rows)
{
object[] array = row.ItemArray;
Dts.Variables["User::var_CreateDate"].Value = array[0].ToString();
}
Dts.TaskResult = (int)ScriptResults.Success;
}
This sets my param of #var_CreateDate String type correctly. I tried this on local machine and was able to pass the value to a native instance of sql-server(yes NOT oracle). Just to test my parameters from script task works.
Finally: I'm using VS-2019's MS Oracle Source to pass the value into Oracle cloud server. Sample query's I have tried
"select * from Table where rownum <= 5 and NVL(CREATE_DATE,UPDATE_DATE) = " +"'05-09-2020'"
::::evals to::::
select * from relate.awd_acct_activity where rownum <= 5 and NVL(CREATE_DATE,UPDATE_DATE) = '2020-05-09'
and this works. But value is hard coded.
Try 2:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = " +"'#[User::var_CreateDate]'"
Try 3:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = to_date(" +"'#[User::var_CreateDate]'"+")"
Try 4:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = to_date(" +"'#[User::var_CreateDate]'"+",'YYYY-MM-DD')"
None of try 2 through 4 eval correctly. Can I have some guidance into how to pass this parameter to Oracle cloud.
Thanks.
I'm assuming you're trying to figure out the syntax for a variable, that would hold the query text. You can try something like this:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = to_date(" + "'" + #[User::var_CreateDate] + "'" + ",'YYYY-MM-DD')"

Codeigniter Active record SQL injection

Is below query vulnerable to SQL Injection where $evilInput is from get/post request.
$this->db->select($evilInput);
$this->db->where($evilInput2 ,"abc");
$query = $this->db->get($evilInput3);
$count = $query->num_rows();
and
$this->db->where("a=$evilInput");
I'd like to point out that all these are vulnerable to SQL injection on a default installation of CodeIgniter. The following results have been tested and verified.
1) $this->db->select($evilInput)
Here the input goes after the select keyword.
select evilInput from table_name where column_name = 1;
Here, if my evil input parameter contains something like:
updatexml(null,concat(0x3a,version()),null)-- -
The actual query will become:
select updatexml(null,concat(0x3a,version()),null)-- - from table_name where column_name = 1;
2) $this->db->where($evilInput ,"abc")
Here the input goes to the column name after WHERE clause.
select * from table_name where evilInput = 1;
CodeIgniter will not escape or filter this input. This can be easily exploited with something like:
1=1 and updatexml(null,concat(0x3a,version()),null)-- -
3) $query = $this->db->get($evilInput3)
Here the input goes in the table name.
select * from evilInput where column_name = 1;
CodeIgniter won't prevent SQL Injection if the user input is something like:
information_schema.tables where 1=1 and updatexml(null,concat(0x3a,version()),null)-- -
4) $this->db->where("a=$evilInput")
This is vulnerable to simple SQL Injection because the input is directly concatenated to the SQL query.

How to use SQL query to define table in dbtable?

In JDBC To Other Databases I found the following explanation of dbtable parameter:
The JDBC table that should be read. Note that anything that is valid in a FROM clause of a SQL query can be used. For example, instead of a full table you could also use a subquery in parentheses.
When I use the code:
CREATE TEMPORARY TABLE jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:postgresql:dbserver",
dbtable "mytable"
)
everything works great, but the following:
dbtable "SELECT * FROM mytable"
leads to the error:
What is wrong?
Since dbtable is used as a source for the SELECT statement it has be in a form which would be valid for normal SQL query. If you want to use subquery you should pass a query in parentheses and provide an alias:
CREATE TEMPORARY TABLE jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:postgresql:dbserver",
dbtable "(SELECT * FROM mytable) tmp"
);
It will be passed to the database as:
SELECT * FROM (SELECT * FROM mytable) tmp WHERE 1=0
Code In Scala
val checkQuery = "(SELECT * FROM " + inputTableName + " ORDER BY " + columnName + " DESC LIMIT 1) AS timetable"
val timeStampDf = spark.read.format("jdbc").option("url", url).option("dbtable", checkQuery).load()
Adding an alias is also necessary after the query in parenthesis.

convert Sql query to LINQ query

I have written a sql query like
DECLARE #OpenDays VARCHAR(15)
SET #OpenDays = (SELECT LTRIM(RTRIM(REPLACE(SUBSTRING(OpenDays,3,LEN(OpenDays)),' - ','')))
FROM
(
SELECT DISTINCT
STUFF((SELECT ' - ' + CONVERT(VARCHAR(30),SSF.OpenDayOfWeek )
FROM #FacilityDayOpen SSF
FOR XML PATH('')
), 1, 2, ' ') as OpenDays
FROM #FacilityDayOpen S
) TS
)
How to convert this query into LINQ
it looks like a stored procedure I can recommend you use the following program
http://sqltolinq.com/
but you might want to replace you #values with values you think may work in query and then you so you can check if it working

Getting errors when trying to insert data into a table in Oracle

I am using python 2.7 and the cx_Oracle module. When I try to run the following query:
UPDATE bs_cart
SET qty = qty + :moreBooks
WHERE userid = :userID
AND isbn = :bookNumber;
IF SQL%ROWCOUNT = 0 THEN
INSERT INTO bs_cart
(userid,isbn)
VALUES
(:userID,:bookNumber)
using Cursor.execute() from cx_Oracle I get the following error:
DatabaseError: ORA-00911: invalid character
When I put it in SQL plus it says:
SP2-0734: unknown command beginning "IF SQL%ROW..." - rest of line ignored.
I am trying to make the cart UPDATE if a user already has the selected book in the cart and INSERT if there are no current copies of the book they want in the cart.
The execute method looks like:
ds.execute(sql,moreBooks=howMany,userID=userLoggedIn,bookNumber=booksToBuy)
and each of the parameters are user generated using rawinput() and then checked against a regular expression.
You need to enclose your statements in begin/end Oracle blocks.
Something like:
BEGIN
UPDATE bs_cart
SET qty = qty + :moreBooks
WHERE userid = :userID
AND isbn = :bookNumber;
IF SQL%ROWCOUNT = 0 THEN
INSERT INTO bs_cart (userid,isbn)
VALUES (:userID,:bookNumber);
END;

Resources