How to pass a date variable to an SQL query in Python - sql-server-2012

Python3.5
Sql Server 2012 Standard
package is pypyodbc
This Code Works
myConnection = pypyodbc.connect('Driver={SQL Server};'
'Server=myserver;'
'Database=mydatabase;'
'TrustedConnection=yes')
myCursor = myConnection.cursor()
sqlstr = ("Select * From DB.Table1 Where DB.Table1.Date <= '7/21/2016'")
myCursor.execute(sqlstr)
results = myCursor.fetchall()
However, Date must be a variable passed in by users. I made several mods to sqlstr but continue to error on myCursor.execute: "TypeError: bytes or integer address expected instead of tuple instance"
sqlstr = ("Select * From DB.Table1 Where DB.Table1.Date <= %s", '7/21/2016')
Error
sqlstr = ("Select * From DB.Table1 Where DB.Table1.Date <= '%s'", '7/21/2016')
Error
sqlstr = ("Select * From DB.Table1 Where DB.Table1.Date <= ?", "'7/21/2016'")
Error
var1 = "'7/21/2016'"
sqlstr = ("Select * From DB.Table1 Where DB.Table1.Date <= %s", var1)
and several more. However, I am sure there is one correct way...
Thanks for any help!

I am sure there is one correct way
Yes, it's a parameterized query:
date_var = datetime(2016, 7, 21)
sql = """\
SELECT [ID], [LastName], [DOB] FROM [Clients] WHERE [DOB]<?
"""
params = [date_var] # list of parameter values
crsr.execute(sql, params)
for row in crsr.fetchall():
print(row)

Related

Julia ReadOnlyMemoryError with ODBC SQL query

I'm working on writing a function that queries a SQL database and I'm encountering a ReadOnlyMemoryError() that has me stumped. The issue is that when I run my code as a simple script everything functions as expected. But when I try to wrap the exact same code in a function I get the ReadOnlyMemoryError().
Here's the script version of my code:
using ODBC
using DBInterface
using Dates
using DataFrames
server = "server string "
username = "username "
password = " password"
db = " db name"
start_date=Nothing
end_date=Nothing
if start_date == Nothing || typeof(start_date) != "Date"
start_date = Dates.today() - Dates.Day(30)
end
if end_date == Nothing || typeof(end_date) != "Date"
end_date = Dates.today()
end
query = """ SQL SELECT statement """
connect_string = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=" * server *
";DATABASE=" * db *
";UID=" * username *
";PWD=" * password
conn = ODBC.Connection(connect_string)
df = DBInterface.execute(conn, query) |> DataFrame
This works as expected, the result is a dataframe df with about 500k rows. However, when I try use this same code to make a reusable function I get the error:
using ODBC
using DBInterface
using Dates
using DataFrames
function get_cf_data(start_date=Nothing, end_date=Nothing)
server = " server string "
username = " user name"
password = " password"
db = " db "
if start_date == Nothing || typeof(start_date) != "Date"
start_date = Dates.today() - Dates.Day(30)
end
if end_date == Nothing || typeof(end_date) != "Date"
end_date = Dates.today()
end
query = """ SQL SELECT statement """
connect_string = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=" * server *
";DATABASE=" * db *
";UID=" * username *
";PWD=" * password
conn = ODBC.Connection(connect_string)
df = DBInterface.execute(conn, query) |> DataFrame
return df
end
In this case, when I try to call from REPL get_cf_data() I get ERROR: ReadOnlyMemoryError(). I'm somewhat new to Julia, so any insight would be very much appreciated. Thank you!
As commented, best practice in most programming languages when integrating APIs like ODBC connections is to close and release its resource after usage.
Additionally, consider parameterization (best practice in any language running SQL that passes literal values) where you set up a prepared SQL statement and bind values in a subsequent execute call.
function get_cf_data(start_date=Nothing, end_date=Nothing)
server = " server string "
username = " user name"
password = " password"
db = " db "
if isnothing(start_date) || typeof(start_date) != "Date"
start_date = Dates.today() - Dates.Day(30)
end
if isnothing(end_date) || typeof(end_date) != "Date"
end_date = Dates.today()
end
# PREPARED STATEMENT WITH QMARK PLACEHOLDERS
sql = """SELECT Col1, Col2, Col3, ...
FROM myTable
WHERE myDate BETWEEN ? AND ?
"""
connect_string = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=" * server *
";DATABASE=" * db *
";UID=" * username *
";PWD=" * password
conn = ODBC.Connection(connect_string)
# PREPARE STATEMENT AND BIND PARAMS
stmt = DBInterface.prepare(conn, sql)
df = DBInterface.execute(stmt, (start_date, end_date)) |> DataFrame
DBInterface.close(stmt) # CLOSE STATEMENT
DBInterface.close(conn) # CLOSE CONNECTION
stmt = Nothing; conn = Nothing # UNINTIALIZE OBJECTS
return df
end

how to use ">" or "<" as variable in javafx sqlite query

I have created a combobox in javafx and I want to query the sqlite db for data which are greater or less than what is selected from the combobox.
Combobox have ObservableList "10,20,30,40,50"
My query is " Select * From table Where age ( xxx ) ?"
xxx can be (" >=" or "<=")
this is my query
String qry_age = "Select * From table Where age (>=) ?";
PreparedStatement ps_age = connect.prepareStatement(qry_age);
ps_age.setInt(1,15);
ResultSet rs_age = ps_age.executeQuery();
while (rs_age.next()) {
System.out.println(rs_age.getString("age"));
}
You could simply use string concatenation to construct the query:
String ageCompareOperator = ">="; // or something else e.g. value from ComboBox
String qry_age = "Select * From table Where age " + ageCompareOperator + " ?";
PreparedStatement ps_age = connect.prepareStatement(qry_age);
...

Passing hexadecimal hash value to JDBC query

I have a table in my MYSQL database with hexadecimal(md5 hash values), I pick the values in one Query1 iterate over the resultset RS1 and Now I need to Fetch data from another table which has this hash value in the key column..I get an sql syntax error for executing the same:
String targetQuery = "select hashValue from targettbl ";
String sourceQuery = "select st.* from sourcetbl st where seqNo in" +
"(select seqNo from sourcetblkey where hashValue in (?)" ;
try {
stmt1 = conn.createStatement();
stmt2 = conn.prepareStatement(sourceMD5Query);
rs1 = stmt1.executeQuery(targetMd5Query);
while(rs1.next())
{
stmt2.setString(1, rs1.getString(1));
rs2 = stmt2.executeQuery(sourceQuery);
ResultSetMetaData rsmd = rs2.getMetaData();
int columnsNumber = rsmd.getColumnCount();
while(rs2.next())
{
System.out.println("Source Row");
for(int i=1;i<columnsNumber;i++)
{
System.out.println(""+rs2.getString(i));
}
}
}
Error:
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
Pls help
There is a )missing at end of your statement. Change it to this:
String sourceQuery = "select st.* from sourcetbl st where seqNo in" +
"(select seqNo from sourcetblkey where hashValue in (?))" ;

Upper Function Input parameter in Oracle

I try to prevent SQL injection in SQL query. I used following code to do it but unfortunately I faced some problem. The query is not running in oracle DB:
strQuery = #"SELECT PASSWORD FROM IBK_USERS where upper(user_id) =upper(:UserPrefix) AND user_suffix=:UserSufix AND STATUS_CODE='1'";
//strQuery = #"SELECT PASSWORD FROM IBK_CO_USERS where user_id = '" + UserPrefix + "' AND user_suffix='" + UserSufix + "' AND STATUS_CODE='1'";
try
{
ocommand = new OracleCommand();
if (db.GetConnection().State == ConnectionState.Open)
{
ocommand.CommandText = strQuery;
ocommand.Connection = db.GetConnection();
ocommand.Parameters.Add(":UserSufix", OracleDbType.Varchar2,ParameterDirection.Input);
ocommand.Parameters[":UserSufix"].Value = UserSufix;
ocommand.Parameters.Add(":UserPrefix", OracleDbType.Varchar2,ParameterDirection.Input);
ocommand.Parameters[":UserPrefix"].Value = UserPrefix.ToUpper();
odatareader = ocommand.ExecuteReader();
odatareader.Read();
if (odatareader.HasRows)
{
Your parameters shouldn't contain the semicolon :. This is just an indicator in your query that the variable that follows is a parameter, but you don't have to supply that on the .NET side:
ocommand.Parameters["UserSufix"] = ...

Using a SELECT statement to return a row where a DateTime column = variable of type Date?

I am using OleDb, trying to do this:
Dim d as Date = DateSerial(Year(rptDate), Month(rptDate), 1 - 1)
Dim conn as OleDbConnection = new OleDbConnection(connStr)
Dim cm as OleDbCommand = new OleDbCommand()
conn.Open()
cm.Connection = conn
cm.CommandText = "SELECT * FROM history WHERE ReportDate = " & d
Okay, so I know it returns 1 row because I'm staring at it in SQL Server. Here is what I've tried so far for the query in the last line, none work:
"SELECT * FROM history WHERE ReportDate = " & d
"SELECT * FROM history WHERE ReportDate = " & d.toString("G")
"SELECT * FROM history WHERE ReportDate = '" & d & "'"
"SELECT * FROM history WHERE ReportDate = '" & d.toString("G") & "'"
"SELECT * FROM history WHERE ReportDate = '#" & d & "#'"
"SELECT * FROM history WHERE ReportDate = #" & d & "#" 'These last 2 with toString
I have also tried:
cm.CommandText = "SELECT * FROM history WHERE ReportDate = ?"
cm.Parameters.Add(d)
cm.CommandText = "SELECT * FROM history WHERE ReportDate = ?"
cm.Parameters.Add(d.toString("G"))
cm.CommandText = "SELECT * FROM history WHERE ReportDate = '?'"
cm.Parameters.Add(d.toString("G"))
cm.CommandText = "SELECT * FROM history WHERE ReportDate = '?'"
cm.Parameters.Add(d)
Clearly I am missing something here, help? I know that d is the same date as the one in SQL server, specifically 3/31/2011 12:00:00 AM.
Write
cm.CommandText = "SELECT * FROM history WHERE ReportDate = ?"
cm.Parameters.AddWithValue("ParamName", d)
Depending on your provider, you may need to use named parameters:
cm.CommandText = "SELECT * FROM history WHERE ReportDate = #date"
cm.Parameters.AddWithValue("date", d)
Try using another date format in your SQL such as:
Cm.CommandText = "SELECT * FROM history WHERE ReportDate = '" & d.toString("mm/dd/yyyy") & "'"
Did you mean to create your date variable (d) as the day before the rptDate value (ie. with a day of zero (1-1)) ?
This (below) will get you your record (assuming the record has no time part).
SELECT * FROM history WHERE ReportDate = '" & d.toString("dd-MMM-yyyy") & "'"
(The explicit date format is unambiguous, whereas "G" is not.)
...or...
cm.CommandText = "SELECT * FROM history WHERE ReportDate = #date"
cm.Parameters.AddWithValue("#date", d)
Your query as stated is asking "give me all the entries for exactly midnight on this date".
Something like this should hopefully work:
cm.CommandText = "DECLARE #MyDate DATETIME; SET #MyDate = ?; SELECT * FROM history WHERE ReportDate >= #MyDate AND ReportDate < DateAdd(day,1,#MyDate);"
cm.Parameters.Add(d)
This will return all entries on or after midnight of the date and before midnight of the next day.