I have a variable that holds multiple data, and I want to insert this multiple data into PostgreSQL database using a single query.
the field on my table is this: stud_tbl(id,fname,lname)
and this is the variable that holds multiple data;
variable = (123,ron,lum),(234,nald,bay),(345,rol,lumz)
my query:
str = "insert into stud_tbl values ('" & variable & "')"
when I execute my query their was an error and I can't identify the error.
To expand on #Patrick's comment:
variable = "(123,'ron','lum'),(234,'nald','bay'),(345,'rol','lumz')"
the query:
str = "insert into stud_tbl values " & variable
Though the usual warnings (How can I prevent SQL injection in PHP?) about this not being best practice apply.
Value of your variable should be enclosed with quotation marks
variable = "(123,ron,lum),(234,nald,bay),(345,rol,lumz)"
Related
What is wrong with my logic below, is there any alternative to get calculatable column which will sum Balances for every unique KEY ?
Purpose: To create a summary column, calculation of Balances for each unique Key created ( Sort Code + Source Account) which will be used later to define whether acc type is Dr/Cr.
Code: below code should create summary column , but every time it triggers error depicted in attached screenshot.
***' Creating Sum of Balances based on Key , to differtiate Dr/Cr Account types
DoCmd.RunSQL "ALTER TABLE Output_File ADD Summing varchar(255)"
DoCmd.RunSQL "UPDATE Output_File SET Summing =" _
& "(SELECT SUM(Output_File.CURR_VALUE)" _
& " FROM Output_File GROUP BY Output_File.`UNIQUE KEYS`)"***
Error:
Error
In MS Access SQL, update queries must be updateable or not read-only. Any use of subqueries renders the query read-only. See Allen Browne's Why is my query read-only? One workaround is to use domain aggregates such as DSum available in Access SQL and VBA.
Ideally, too, consider using a saved query and avoid the need of building long SQL statements in VBA and have to worry about line breaks and concatenations. Below assumes UNIQUE KEYS is a number field. If text field, wrap in single quotes. If a date field, wrap in hashtags/pound symbols.
SQL (save as stored query)
UPDATE Output_File o
SET Summing = DSum("CURR_VALUE", "Output_File", "`UNIQUE KEYS` = " & o.`UNIQUE KEYS`)
VBA (reference above saved query)
DoCmd.OpenQuery "mySavedQuery" ' NO NEED TO CLOSE ACTION QUERIES
CurrentDb.Execute "mySavedQuery" ' ALTERNATIVE CALL
I have 3 sql tables customer, employee and manager. I want to access dynamically to my tables. I had a statement like this,
"update customer set AMOUNT where ID= ?"
But in this situation i can only access to customer. I need to access all of the tables for different operations. Is that possible to write this,
"update ? set AMOUNT where ID=?"
or what can i do to access for example employee for a different class.
The parameters can be used only in the place where you could otherwise use a literal value, like a quoted string or a numeric value.
Parameters cannot be used for identifiers like table names. Nor expressions. Nor SQL keywords.
All those other parts of the query must be fixed in the SQL query string before you prepare the query.
To query other tables, you just have concatenate the table name into the string.
String query = "update " + tableName + " set amount where ID=?";
It's up to you to make sure your variable tableName in fact only contains one of your table names. A good way to do this is to compare it to a list of known table names, and if it isn't in the list, throw an exception.
I am trying to add a number sequentially to a field for a job number in a do loop. My code is not breaking but it is not adding the records to the table. The code is written in a function that is being called when the access form button is pressed to update the records. Below is my code:
Dim NumofBatches As Integer
NumofBatches = [Batches]
Dim startnum As Integer
startnum = 1
Dim jobnum As String
jobnum = [JobNumber]
Do While startnum <= NumofBatches
Dim mynumString As String
mynumString = startnum
DoCmd.RunSQL "INSERT INTO Production (CardCode,JobItemNo,JobIndex,DrawingRef,DRDescription,[CreationDate],Quantity,FinishDate,LastLocation,DateLastMoved) VALUES ('" & jobnum & mynumString & "', ItemNumber, JobNumber, DrawingRef, DRDescription, [CreationDate], Quantity, FinishDate, LastLocation, DateLastMoved)"
startnum = startnum + 1
Loop
I realize I will have duplicated rows of fields except for the cardcode field which is what I am trying to achieve. The cardcode fields should be sequential in each row for the jobnumber. An example, 100011, 100012, where 10001 is the job number and it is adding 1, 2, etc. sequentially.
You have a couple of problems. The first is in the field list in the INSERT part of your SQL statement. Unless you have a column in your Production table named "CardCode + mynumString" (and if you did it would have to have square brackets around it because it has a space and a symbol in it) it's not going to work. Inside the parentheses after INSERT INTO <TableName> you have to list column names from the table you are inserting into. Fix your target column names first.
Next you have a SELECT statement as the source of values you're inserting. Unless the values you need are found in a table, you should probably use a VALUES list:
INSERT INTO <TableName> (Col1, Col2, ...) VALUES (Val1, Val2, ...)
The final issue is that you have to concatenate your variables into the SQL string. I'm going to assume that [Text90] is a control with your CardCode value in it and you're wanting to concatenate it with mynumString. That would look something like this:
DoCmd.RunSQL "INSERT INTO Production (Col1, Col2, ...) VALUES ('" & [Text90] & mynumString & "', Val2, ...)"
Note that you have to resolve your value outside of the quoted SQL string and concatenate that value into the string and set all of that off with single-tick quotes inside the SQL string.
I find it handy to build dynamic SQL strings like this using a variable and then execute it as:
DoCmd.RunSQL mySQLVariable
Having the SQL string in a variable makes it a little easier to spot errors in the concatenation if you inspect the variable during debugging or if you just dump the value to the immediate window with Debug.Print.
I have been reading up on escaping strings to avoid SQL Injection. I do understand that parameterized queries are the safest way to avoid Injection.
But i do have a question regarding Escaping as means of complimenting Parameterized queries.
Suppose the input field "Name" had the value O'Brian and was escaped using the below routine:
sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"
So the value now looks like O''Brian. If this were to be inserted in the database using the Insert query, will the inserted value be actually O''BRIAN?
If that is the case, then in order to search the name column for the inserted value O''Brian, will i have to escape it to O''Brian before executing the Select query to match it with the value inserted in the DB?
Try
Using connection As New SqlConnection(ConnectionString)
connection.Open()
SQL = "SELECT #PARAM FROM SystemOps"
sqlCmd = New SqlClient.SqlCommand(SQL, connection)
sqlCmd.Parameters.Add(New SqlClient.SqlParameter("#PARAM", SqlDbType.VarChar)).Value = "SystemNavn"
' .. and so on...
When I run the code, it returns with a result of "SystemNavn" (which is the name of the column in the table), instead of the value of that column in the current row. What am I doing wrong?
You cannot use parameter names for column names, or any other SQL syntax. You can only use parameters as placeholders for literal values. Parameters always get replaced with the literal form for the value, so in your example, the command which is being run, essentially, gets evaluated as:
SELECT 'SystemNavn` FROM SystemOps
In order to have a variable column name, like that, I would recommend dynamically building the SQL string, like this:
Dim columnName As String = "SystemNavn"
SQL = "SELECT [" & columnName & "] FROM SystemOps"
However, by doing so, you are opening yourself up to potential SQL-injection attacks, so you need to be careful. The safest way, that I'm aware of, to avoid an attack in a situation like this is to get the list of column names from the database and compare the columnName variable against that list to ensure that it is actually a valid column name.
Of course, if the column name never changes, then there's no reason to make it a variable at all. In that case, just hard-code it directly into the SQL command, thereby avoiding the necessity for parameters or variables at all:
SQL = "SELECT SystemNavn FROM SystemOps"
Your query doesn't need any parameters in this case. just do
SQL = "SELECT SystemNavn FROM SystemOps"
This is secure. If later you need to filter this, you can do something like:
SQL = "SELECT SystemNavn FROM SystemOps WHERE COL_A = #ColA"
FYI, for your code above, since it is a VARCHAR type, it is being executed like so:
SELECT 'SystemNavn' FROM SystemOps
That is why you're getting 'SystemNavn' back.
You cannot use a parameter to specify the name of a column or a table.
The parameters collection are used to specify the values to search for, to insert, to update or delete.
Your code should be changed to something like this
Using connection As New SqlConnection(ConnectionString)
connection.Open()
SQL = "SELECT SystemNavn, <other fiels if needed> " & _
"FROM SystemOps WHERE <keyfield_name> = #PARAM"
sqlCmd = New SqlClient.SqlCommand(SQL, connection)
sqlCmd.Parameters.AddWithValue("#PARAM", paramValue)
......
End Using
Of course the example above assumes that you have a WHERE clause, if you want to retrieve every value of the column SystemNavn without condition, then you don't need a parametrized query because every part of your sql command is provided by you and there is no worry for sql injection.