I'm attempting to execute a simple query that inserts two names, "self.player1", and "self.player2" as VARCHAR datatypes into a table on a MySQL server version 8.0.31. When I call a custom-built function called "execute_query()" provided below, I receive the following error in my terminal:
Error: '1054 (42S22): Unknown column 'Jo' in 'field list''
Function Definition of "execute_query()":
def execute_query(self, query):
''' This function takes SQL queries stored
in Python as strings and passes them
to the "cursor.execute()" method to
execute them on the server'''
cursor = self.connection.cursor()
try:
cursor.execute(query)
self.connection.commit() # Implements commands detailed in SQL queries
print(query + "Query successful")
except Error as err:
print(f"Error: '{err}'")
The names of the attributes are "player_1" and "player_2", and the values to be inserted are assigned to variable names "self.player1", and "self.player2" as shown below.
query = "USE " + self.db_obj.db_name + ";"
self.db_obj.execute_query(query)
query = "INSERT INTO `match`(player_1, player_2) VALUES (" + self.player1 + "," + self.player2 + ");"
It is important to mention that the issue is not with the "execute_query()" function as I have been able to successfully execute other queries. Additionally, I have run through numerous other similar issues on this discussion forum and have tried dropping triggers, changing secure file priviliges, and hardcoding the value of my entries into the query as opposed to concatenating the values to other strings to produce the resultant query, and have not had any luck.
The design of the table, match is provided below (Note: I was not able to write out the contents of this query to a text file using the following command:
SELECT * FROM `match`
INTO OUTFILE "test.txt";
as I received this error:
The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
The query that I used to generated the table in the image below is:
DESCRIBE `match`;
Your error says : Error: '1054 (42S22): Unknown column 'Jo' in 'field list''.
The word 'Jo' in the error is not a field name but a player name. You need to modify your query to :
query = "INSERT INTO `match`(player_1, player_2) VALUES ('" + self.player1 + "','" + self.player2 + "');"
Since string values need to be between single quotes.
Related
when trying to update my mysql database-column with following sql command
UPDATE db.vendor_horses SET image='{"images":["' + image + '"]}';
I get following error:
UPDATE db.vendor_horses SET image='{"images":["' + image + '"]}' Error Code: 1292. Truncated incorrect DOUBLE value: '{"images":["' 0.00028 sec
I can't figure out what's wrong..
in mysql + is not valid concatenation sign. (MySQL concatenation operator)
you should use CONCAT function.
UPDATE db.vendor_horses SET image= CONCAT('{"images":["', image, '"]}';
To avoid DRY, I'm attempting to create an sql INSERT statement with variable column names and the data to fill those columns via ScalikeJDBC's sql interpolation:
case class MySQLInsertMessage(tableName:String, columns:List[String], values:List[String])
def depositMessage(msg: MySQLInsertMessage): Unit = {
NamedDB('MySQLMsgDepositor) localTx { implicit session =>
val sqlStmt = sql"INSERT INTO ${msg.tableName} (${msg.columns}) VALUES (${msg.values})"
println("The sql statement is: " + sqlStmt.statement)
println("The parameters are: " + sqlStmt.parameters)
sqlStmt.update().apply()
}
}
And when I call this with:
depositMessage(MySQLInsertMessage("My_Table", List("key", "email"), List("42", "user#email.com")))
the resulting console printout is:
The sql statement is: INSERT INTO ? (?, ?) VALUES (?, ?)
The
parameters are: List(My_Table, key, email, 42, user#email.com)
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 ''My_Table'
('key', 'email') VALUES ('42', 'user#emai' at line 1
java.sql.SQLSyntaxErrorException: 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 ''My_Table' ('key', 'email') VALUES
('42', 'user#emai' at line 1
I've tried wrapping the sql"..." as such instead:sql"""...""", but that doesn't seem to make a difference. I can execute the expected statement just fine in my MySQL workbench GUI. Any idea what my syntax error is?
Stemming from the hint from #scaisEdge, it seems ScalikeJDBC, when using its syntax, will always place single quotes around any parameterized values. And judging from here - https://github.com/scalikejdbc/scalikejdbc/issues/320 - this is a known issue.
With a MySQL INSERT statement (or others), your table name or column values may not have single quotes around them, though they are allowed to have backticks.
You can use their SQLSyntax.createUnsafely(str:String) method, or, if I wanted to do this as I was doing above, instead of using sql"...", I could use the old way of SQL(s"INSERT INTO ${msg.tableName} (${msg.columns.mkString(",")})")
Note - I believe both of these leave you open to injection attacks. Since, for me, this is a local API and you'd have to have the DB's username and password regardless to use it, I'm going with the createUnsafely way of doing things, with a little regex "cleaner" for a little inelegant piece of mind:
def depositMessage(msg: MySQLInsertMessage): Unit = {
NamedDB('MySQLMsgDepositor) localTx { implicit session =>
val unsafeSQLRegex = "[`'\"]".r
val table = SQLSyntax.createUnsafely(s"`${unsafeSQLRegex.replaceAllIn(msg.tableName, "")}`")
val columns = SQLSyntax.createUnsafely(msg.columns.map(value => unsafeSQLRegex.replaceAllIn(value, "")).mkString("`", "`, `", "`"))
val sqlStmt = sql"INSERT INTO $table ($columns) VALUES (${msg.values})".update().apply()
}
}
}
Very similar to this question MySQL Dynamic Query Statement in Python
However what I am looking to do instead of two lists is to use a dictionary
Let's say i have this dictionary
instance_insert = {
# sql column variable value
'instance_id' : 'instnace.id',
'customer_id' : 'customer.id',
'os' : 'instance.platform',
}
And I want to populate a mysql database with an insert statement using sql column as the sql column name and the variable name as the variable that will hold the value that is to be inserted into the mysql table.
Kind of lost because I don't understand exactly what this statement does, but was pulled from the question that I posted where he was using two lists to do what he wanted.
sql = "INSERT INTO instance_info_test VALUES (%s);" % ', '.join('?' for _ in instance_insert)
cur.execute (sql, instance_insert)
Also I would like it to be dynamic in the sense that I can add/remove columns to the dictionary
Before you post, you might want to try searching for something more specific to your question. For instance, when I Googled "python mysqldb insert dictionary", I found a good answer on the first page, at http://mail.python.org/pipermail/tutor/2010-December/080701.html. Relevant part:
Here's what I came up with when I tried to make a generalized version
of the above:
def add_row(cursor, tablename, rowdict):
# XXX tablename not sanitized
# XXX test for allowed keys is case-sensitive
# filter out keys that are not column names
cursor.execute("describe %s" % tablename)
allowed_keys = set(row[0] for row in cursor.fetchall())
keys = allowed_keys.intersection(rowdict)
if len(rowdict) > len(keys):
unknown_keys = set(rowdict) - allowed_keys
print >> sys.stderr, "skipping keys:", ", ".join(unknown_keys)
columns = ", ".join(keys)
values_template = ", ".join(["%s"] * len(keys))
sql = "insert into %s (%s) values (%s)" % (
tablename, columns, values_template)
values = tuple(rowdict[key] for key in keys)
cursor.execute(sql, values)
filename = ...
tablename = ...
db = MySQLdb.connect(...)
cursor = db.cursor()
with open(filename) as instream:
row = json.load(instream)
add_row(cursor, tablename, row)
Peter
If you know your inputs will always be valid (table name is valid, columns are present in the table), and you're not importing from a JSON file as the example is, you can simplify this function. But it'll accomplish what you want to accomplish. While it may initially seem like DictCursor would be helpful, it looks like DictCursor is useful for returning a dictionary of values, but it can't execute from a dict.
I got this error while debugging in SSIS:
Error: 0xC0049064 at Data Flow Task, Derived Column [70]: An error occurred while attempting to perform a type cast.
Error: 0xC0209029 at Data Flow Task, Derived Column [70]: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "component "Derived Column" (70)" failed because error code 0xC0049064 occurred, and the error row disposition on "output column "EVENT_DT" (118)" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure.
Error: 0xC0047022 at Data Flow Task: SSIS Error Code DTS_E_PROCESSINPUTFAILED. The ProcessInput method on component "Derived Column" (70) failed with error code 0xC0209029. The identified component returned an error from the ProcessInput method. The error is specific to the component, but the error is fatal and will cause the Data Flow task to stop running. There may be error messages posted before this with more information about the failure.
Error: 0xC0047021 at Data Flow Task: SSIS Error Code DTS_E_THREADFAILED. Thread "WorkThread0" has exited with error code 0xC0209029. There may be error messages posted before this with more information on why the thread has exited.
Information: 0x40043008 at Data Flow Task, DTS.Pipeline: Post Execute phase is beginning.
Information: 0x40043009 at Data Flow Task, DTS.Pipeline: Cleanup phase is beginning.
Information: 0x4004300B at Data Flow Task, DTS.Pipeline: "component "DataReaderDest" (143)" wrote 0 rows.
Task failed: Data Flow Task
Warning: 0x80019002 at Package: SSIS Warning Code DTS_W_MAXIMUMERRORCOUNTREACHED. The Execution method succeeded, but the number of errors raised (4) reached the maximum allowed (1); resulting in failure. This occurs when the number of errors reaches the number specified in MaximumErrorCount. Change the MaximumErrorCount or fix the errors.
SSIS package "Package.dtsx" finished: Failure.
My expression is:
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + EVENT_T)
My original data are in this sequence:
EVENT_D: DD/MM/YYYY
EVENT_T: HH:MM:SS
Any help are appreciated. I have try changing my expression numerous time but still fails.
I suspect that there are some date time values which are not in the correct format .So SSIS throws error while parsing them .
In order to find to incorrect date time value from your source table try to redirect the error rows from Derived Transformation and check the incorrect data using a data viewer
The problem with substring values are if the string data are not in the correct format then the Derived Transformation will throw error .
In your OLEDB source component try to write the sql and get only the correct datetime values
Ex:
Select col1,
case when isDate(EVENT_D) = 1 THEN EVENT_D ELSE NULL
END as [EVENT_D],
Col2,EVENT_T,other columns
from yourTable
in your derived transformations use your code to convert into DT_DBTIMESTAMP type .
Else Try to use a script component and parse the EVENT_D and EVENT_T values and convert to datetime values. No need to use Derived column with all those substring values
create a New Output column Valid_D with the datatype as DT_DBTIMESTAMP.Select the 2 input columns EVENT_D and EVENT_T in the available input Columns in Script Transformation Editor
VB.NET code
Dim result As DateTime
If DateTime.TryParseExact(Row.EVENT_D, "dd/MM/yyyy",
Nothing, Globalization.DateTimeStyles.None, result) Then
Row.ValidD = result.Add (TimeSpan .Parse (Row.EventT ) );
End If
C# code
DateTime result;
if (DateTime.TryParseExact(Row.EventD, "dd/MM/yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.None,out result))
{
Row.ValidD = result.Add (TimeSpan .Parse (Row.EventT ) );
}
Now you can use Valid_D column which is of DateTime type in your subsequent transformations
Update : The problem with your syntax is you cannot add date+ time in the string format . You need to parse individually both EVENT_D and EVENT_T .
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + EVENT_T)
So your syntax is not valid.
The isDate function shows NULL for 30/04/2012 because as per MSDN
The return value of ISDATE depends on the settings set by
SET DATEFORMAT, SET LANGUAGE and Configure the default language
Server Configuration Option.
but it returns 1 for the value 01/05/2012 and 02/05/2012 because it takes as MM/dd/YYYY
so the 1st date is Jan 5th 2012 instead of May 1st 2012
So the soultion is use script component and parse these values into valid date and time and then use it in your subsequent transformations .
Please check my script transformation code above
Update 2:
I think your using SSIS 2005 .The code should be
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim result As DateTime
If DateTime.TryParseExact(Row.EVENTD, "dd/MM/yyyy", Nothing, Globalization.DateTimeStyles.None, result) Then
Row.ValidD = result.Add(TimeSpan.Parse(Row.EVENTT))
End If
End Sub
after Script transformation ,you don't need to use Derived component .The result obtained in the column Valid_D contains the valid value which is of datetime format
If you wanted to do this without a script, you could have just changed your expression from
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + EVENT_T)
to
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + " " + EVENT_T)
Not having the space between the date and the time portions is what was most likely causing your original error. You were getting
2012-04-3012:25:37
instead of
2012-04-30 12:25:37
I faced the same problem while converting a string containing date to datetimestamp field. It is all due to spaces in the field.
So we need to check for space and then convert it to datetimestamp.
Below is the expression for the same.
LEN(TRIM([Field1])) == 1 ? NULL(DT_DBTIMESTAMP) : (DT_DBTIMESTAMP)(SUBSTRING([Field1],1,4) + "-" + SUBSTRING([Field1],5,2) + "-" + SUBSTRING([Field1],7,2) + " " + SUBSTRING([Field1],10,2) + ":" + SUBSTRING([Field1],12,2))
I am trying to delete multiple rows in the sqlite table in my Adobe AIR app (runtime 2.5).
Here is the statement, using the "IN" operator:
"DELETE FROM mylist WHERE tdId IN (tdId1, tdId2, tdId3, ...)";
Where tdId1, tdId2, etc. will be determined at runtime based on which row(s) the user chooses to delete. The user can delete arbitrary number of rows.
I've tried something like:
//delete statement text
"DELETE FROM mylist WHERE tdId IN :tdId";
//delete statement parameters: take 1.
//Got "argument error: near ':tdId': syntax error"
deleteStmt.parameters[":tdId"] = "(26, 32)";
//delete statement parameters: take 2.
//Also got "argument error: near ':tdId': syntax error"
var arr:Array = [26, 32];
deleteStmt.parameters[":tdId"] = arr;
How I go about deleting multiple rows?
[Edit] So it looks like the aforementioned cached statement with parameter [":tdId"] doesn't work when deleting multiple rows. When attempting to execute the delete statement multiple times in asynchronous mode, after the very first row in the queue is deleted, Flash throws the following error:
"Error #3110: Operation cannot be
performed while SQLStatement.executing
is true."
It would seem too much of trouble to chain these deletes with a callback. So I guess I am using my last resort: building the sql at runtime. Conclusion: Cached statements can't be used in these kind of situations...
The problem occurs when you insert the parameter "(26,32)". As the parameter is not purely a substitution of value, it represents a variable to SQL, NOT A STRING. Hence you statement effectively became (or roughly) in your first take...
"DELETE FROM mylist WHERE tdId IN '(26,32)'"
Hence your error, due to the syntax... In your second take it gets worse...
"DELETE FROM mylist WHERE tdId IN *Array(26,32)*"
As the variable does not convert to a string value, this does not actually happen. But what happens is that when the interprater (SQL) tries to understand the code after the 'IN' text, it gets an ARRAY object, which it has completely no idea on what to do... Its not even a valid SQL type....
Solution? [I yet to fully test it, so please do]
var toDel:Array = [26,32]
//delete statement text
var baseStr:String = "DELETE FROM mylist WHERE tdId IN (";
var midStr:String = '';
//delete statement parameters: Processing parameter
for( var i = 0; i < toDel.length; i++ ) {
deleteStmt.parameters[i] = toDel[i];
if(midStr.length > 0) { midStr += ' , '; }
midStr += '?';
}
deleteStmt.text = baseStr + midStr + ' )';
//Then execute
So what happens in this case is that u effectively execute...
"DELETE FROM mylist WHERE tdId IN ( :val1 , :val2 )"
In this way you still maintain the safe (good practice) use of parameters, without converting everything to a string.
EDIT: if you dun understand the use of parameter / '?' refer to :
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/data/SQLStatement.html#parameters
If the IN clause does not allow parameters, you can try old-school SQL style: append multiple
" OR (tdId = :param" + paramCounter.toString() + ")"
to the SQL string