fetchall error in PDO - prepared-statement

I'm trying to write code to insert new items into a database.
if(isset($_POST['btnAddVeg'])){
$addVegType = $_POST['txtAddVegType'];
$AddVegName = $_POST['txtAddVegName'];
$insertQuery = 'insert into vegetables (vegetable_type, vegetable_id) values ("$addVegType", "$AddVegName")';
$statement2 = $db->prepare($insertQuery);
$statement2->execute();
$results2 = $statement2->fetchAll();
$statement2->closeCursor();
foreach($results2 as $result2){
echo "<table border = '0'><th>ID</th><th>Type</th><th>Name</th> <tr><td>".$result2['vegetable_id'].'</td>';
echo "<td>".$result2['vegetable_type'].'</td>';
echo "<td>".$result2['vegetable_name'].'</td></tr></table>';
}
I get this error:
Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error in /vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/task9.php(54): PDOStatement->fetchAll() #1 {main} thrown in vvvvvvvvvvv/task9.php on line 54
Probably ridiculously easy but what am I missing?
Thank you

Executing an INSERT statement doesn't return a resultset object.
Just remove the line that does the statement2->fetchAll.
And remove the lines that reference $results2.
We would need that if we were executing a SELECT statement, to get a resultset (a set of rows) returned.
Also important to point out: the code is vulnerable to SQL Injection.
https://xkcd.com/327/
https://www.owasp.org/index.php/SQL_Injection

Related

JavaScript in Snowflake Stored Procedure

I am getting error for the code below
I am trying to load log table with below columns
SP_MASTER_VIEW_TO_TABLES_RS
V_QUOTE_VIEWNAMES_TO_BE_LOADED_TO_TABLE
these are the variables defined within SP
var V_INSERT_DIM_MASTER_SP_LOG_RS = `INSERT INTO DB.SCHEMA.TABLENAME
SELECT ` + SP_MASTER_VIEW_TO_TABLES_RS + ` ,` + V_QUOTE_VIEWNAMES_TO_BE_LOADED_TO_TABLE + ` ,` + `getdate(), ''EXECUTED SUCCESSFULLY'';`
var V_EXEC_INSERT_DIM_MASTER_SP_LOG_RS = snowflake.createStatement( {sqlText: V_INSERT_DIM_MASTER_SP_LOG_RS} );
var V_RESULT_INSERT_DIM_MASTER_SP_LOG_RS = V_EXEC_INSERT_DIM_MASTER_SP_LOG_RS.execute();
V_RESULT_INSERT_DIM_MASTER_SP_LOG_RS.next();
Error
Execution error in store procedure SP_MASTER_SP: SQL compilation error: syntax error line 2 at position 72 unexpected '('. parse error line 28 at position 63 near '32'. parse error line 29 at position 138 near '44'. parse error line 52 at position 64 near '32'. parse error line 53 at position 138 near '44'. At Statement.execute, line 54 position 98
It's really hard to debug without seeing the real procedure. If you can't share the real procedure, please create a simplified version, run it and share the error belonging to the procedure.
I see that you directly add SP_MASTER_VIEW_TO_TABLES_RS and V_QUOTE_VIEWNAMES_TO_BE_LOADED_TO_TABLE variables to the SQL statement, so the value of them is important. Can't you share something like this?
create or replace procedure proc()
returns string
language javascript
as
$$
SP_MASTER_VIEW_TO_TABLES_RS = 'abc';
V_QUOTE_VIEWNAMES_TO_BE_LOADED_TO_TABLE = 'xyz';
var V_INSERT_DIM_MASTER_SP_LOG_RS = `INSERT INTO DB.SCHEMA.TABLENAME
SELECT ` + SP_MASTER_VIEW_TO_TABLES_RS + ` ,` + V_QUOTE_VIEWNAMES_TO_BE_LOADED_TO_TABLE + ` ,` + `getdate(), 'EXECUTED SUCCESSFULLY';`
var V_EXEC_INSERT_DIM_MASTER_SP_LOG_RS = snowflake.createStatement( {sqlText: V_INSERT_DIM_MASTER_SP_LOG_RS} );
var V_RESULT_INSERT_DIM_MASTER_SP_LOG_RS = V_EXEC_INSERT_DIM_MASTER_SP_LOG_RS.execute();
V_RESULT_INSERT_DIM_MASTER_SP_LOG_RS.next();
$$;
Although all these details are missing, I noticed that this part has an error:
`getdate(), ''EXECUTED SUCCESSFULLY'';`
You should not use double "single quotes", so it should be like this:
`getdate(), 'EXECUTED SUCCESSFULLY';`

How do I work with variables in snowflake

I set this up a while ago in something that is not really used. I was under the impression that it worked at the time, but I'm trying to test it now and am getting some errors.
Here is my snowflake code:
var rs = snowflake.createStatement( { sqlText: "select count(*) from toptal.stage_resellers" } ).execute();
rs.next();
var resellers = rs.getColumnValue(1);
I that that var resellers was going to define a variable that would have the number of rows in stage_resellers, but I'm not confident of that.
I decided to test it just by inserting the value into a logging table that I am using into an unused column for the time being.
Here is that code:
var stmt1 = snowflake.execute ( { sqlText:`insert into toptal.processing_executions values ('merge into dim_resellers', current_timestamp, 'processing', :resellers);`});
I'm getting this error:
Execution error in store procedure PROCESSING: SQL compilation error: error line 1 at position 110 Bind variable :resellers not set. At Snowflake.execute, line 47 position 24
I tried futzing around with setting the variable, to no avail.
I have a feeling that I am mixing up environments here, but I'm not sure what's going on.
To execute:
var stmt1 = snowflake.execute ( { sqlText:`insert into toptal.processing_executions values ('merge into dim_resellers', current_timestamp, 'processing', :resellers);`});
variables has to be provided as ? or :1. Code becomes:
var stmt1 = snowflake.execute({
sqlText: `insert into toptal.processing_executions
values ('merge into dim_resellers', current_timestamp,
'processing', ?)`
,binds: [resellers] } );
More at documentation: Binding Variables

Execution error in stored procedure in Snowflake

I compiled a stored procedure but I'm unable to execute it - getting this error:
Execution error in stored procedure SAMPLE_ETL_MONITORING_PROC: Stored procedure execution error: Requested information on the current user is not accessible in stored procedure. At Statement.execute, line 18 position 45
I have write access to the database but not sure If I have to include any commands/statements in the script. Can anyone please suggest what needs to be done?
Here is the script:
CREATE OR REPLACE PROCEDURE sample_etl_monitoring_proc()
returns string not null
language javascript
as
$$
var insert_cmd = `
truncate table OOBE.monitoring.load_history_1
`
var sql_insert = snowflake.createStatement({sqlText: insert_cmd});
var insert_result = sql_insert.execute();
var stream_select_cmd = `
insert into OOBE.monitoring.load_history_1
select * from (
select * from OOBE.information_schema.load_history
union
select * from snowplow.information_schema.load_history);
`
var sql_select_stream = snowflake.createStatement({sqlText: stream_select_cmd});
var select_stream_result = sql_select_stream.execute();
return '👍';
$$;
I reproduced the error and got this to work by adding an explicit caller's right declaration:
CREATE OR REPLACE PROCEDURE sample_etl_monitoring_proc()
returns string not null
language javascript
execute as caller
as

PreparedStatement not populating

I have PreparedStatement(ps) below, populate it as shown and when executed MSSQL errors as shown last below. Of course there is NO value of "TRADEIN" in any data that can be seen. Ideas?
String update = "UPDATE IM_ITEM SET "
+ "LST_COST=?, PRC_1=?, IS_TXBL=?, TAX_CATEG_COD=?,CATEG_COD=?"
+ " WHERE ITEM_NO="+itemNo;
populate:
ps.setString(++i, q.get("LST_COST"));
ps.setString(++i, q.get("PRC_1"));
ps.setString(++i, q.get("IS_TXBL"));
ps.setString(++i, q.get("TAX_CATEG_COD"));
ps.setString(++i, q.get("CATEG_COD"));
debugged: "sqlCommand" and "userSQL" are still parameterized only
UPDATE IM_ITEM SET LST_COST=?, PRC_1=?, IS_TXBL=?, TAX_CATEG_COD=?, CATEG_COD=? WHERE ITEM_NO=101316
error:
Severe: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the varchar value 'TRADEIN' to data type int.
Answered, kindly, by Seanlange in the chat.

Perl ADO thinks printed output in stored procedure is an error!

First of all (in case this is important) I'm using ActiveState's Perl (v5.8.7 built for MSWin32-x86-multi-thread).
I've just emerged from a three hour long debugging session, trying to find the source of an error. I found there was simply no error, but for some reason ADO's connection object was getting the Errors.Count increased with each printed message in my stored procedure's output.
Consider following Transact SQL code:
CREATE PROCEDURE dbo.My_Sample() AS
BEGIN TRAN my_tran
-- Does something useful
if ##error <> 0 BEGIN
ROLLBACK TRAN my_tran
RAISERROR( 'SP My_Sample failed', 16, 1)
END ELSE BEGIN
COMMIT TRAN my_tran
PRINT 'SP My_Sample succeeded'
END
Now imagine a Perl sub more or less like:
sub execute_SQL {
# $conn is an already opened ADO connection object
# pointing to my SQL Server
# $sql is the T-SQL statement to be executed
my($conn, $sql) = #_;
$conn->Execute($sql);
my $error_collection = $conn->Errors();
my $ecount = $error_collection->Count;
if ($ecount == 0 ) { return 0; }
print "\n" . $ecount . " errors found\n";
print "Executed SQL Code:\n$sql\n\n";
print "Errors while executing:\n";
foreach my $error (in $error_collection){
print "Error: [" . $error->{Number} . "] " . $error->{Description} . "\n";
}
return 1;
}
Somewhere else, in the main Perl code, I'm calling the above sub as:
execute_SQL( $conn, 'EXEC dbo.My_Sample' );
In the end I got it that every PRINT statement causes a new pseudo-error to be appended to the ADO Errors collection. The quick fix I implemented was to change that PRINT in the SP into a SELECT, to bypass this.
The questions I'd like to ask are:
Is this behaviour normal?
Is there a way to avoid/bypass it?
This is to be expected as it's what ADO does and the Win32::ADO is quite a thin layer above it.
ref: knowledge base note that the RAISERROR and PRINT statements are returned through the ADO errors collection
OK, after a lot of testing and reading, I came to found it explained in the BOLs' article "Using PRINT" (my emphasis):
The PRINT statement is used to return messages to applications. PRINT takes either a character or Unicode string expression as a parameter and returns the string as a message to the application. The message is returned as an informational error to applications using the SQLClient namespace or the ActiveX Data Objects (ADO), OLE DB, and Open Database Connectivity (ODBC) application programming interfaces (APIs). SQLSTATE is set to 01000, the native error is set to 0, and the error message string is set to the character string specified in the PRINT statement. The string is returned to the message handler callback function in DB-Library applications.
Armed with this knowledge I adapted this VB6 from this DevX article until I got this:
sub execute_SQL {
# $conn is an already opened ADO connection object
# pointing to my SQL Server
# $sql is the T-SQL statement to be executed
# Returns 0 if no error found, 1 otherwise
my($conn, $sql) = #_;
$conn->Execute($sql);
my $error_collection = $conn->Errors();
my $ecount = $error_collection->Count;
if ($ecount == 0 ) { return 0; }
my ($is_message, $real_error_found);
foreach my $error (in $error_collection){
$is_message = ($error->{SQLState} eq "01000" && $error->{NativeError}==0);
$real_error_found=1 unless $is_message;
if( $is_message) {
print "Message # " . $error->{Number}
. "\n Text: " . $error->{Description} ."\n";
} else {
print "Error # " . $error->{Number}
. "\n Description: " . $error->{Description}
. "\nSource: " . $error->{Source} . "\n";
}
}
print $message_to_print;
return $real_error_found;
}
So now my Perl sub correctly sorts out real errors (emitted from SQL Server via a RaisError) and a common message outputted via "PRINT".
Thanks to Richard Harrison for his answer which lead me to the way of success.

Resources