I am trying to get the number of rows affected by an update query. I am using a pool connection to a SQL server database. The rows update fine, but I can't figure out how to get the number of rows affected which I want to display for the user. I have read the documentation of dbExecute and it says:
dbExecute() always returns a scalar numeric that specifies the number
of rows affected by the statement. An error is raised when issuing a
statement over a closed or invalid connection, if the syntax of the
statement is invalid, or if the statement is not a non-NA string.
I thought maybe the pool was the issue, so I also tried it with a regular dbConnect, and still got 0 for res.
Can someone show how I can pull out and display to the user the number of rows affected?
observeEvent(input$recupdate, {
res <-
#poolWithTransaction(con2, function(con2) {
dbExecute(con2, paste(
"UPDATE [Test_DB].[dbo].[mlt] SET testvar = 1 where idnum in ('",
trim(paste(filteredData()$idnum, collapse="','")),"')", sep=""))
#})
#print(res)
showModal(modalDialog(
title = "Rows affected:",
res,
easyClose = TRUE,
footer = NULL
))
})
Related
I use ts-postgres and INSERT INTO to add new rows to my table.
import { Client } from 'ts-postgres';
let query = '...';
let res = await Client.query(query, [username, email]);
The result I get from Client.query is the following result:
Result {names: Array(0), rows: Array(0), status: "INSERT 0 1"}
Result {names: Array(0), rows: Array(0), status: "INSERT 0 0"}
In the first case 1 line got added, in the second 0. Do I really need to parse the status string in order to see how many rows got added?
Yep, that's something you have to deal with when working at low level (without ORM)
So here's a simple function to check for inserted rows
checkInserted(result): number {
const status = result.status.split();
return parseInt(status[status.length-1]);
}
you can customize it according to your requirements
It looks like the answer is yes, you really do need to parse the status string.
According to the Postgres protocol documentation, when the database finishes executing an insert command, it sends a CommandComplete message back to the client. The CommandComplete message consists of a byte that identifies the message type, a length, and a "tag," which is a string:
For an INSERT command, the tag is INSERT oid rows, where rows is the
number of rows inserted. oid used to be the object ID of the inserted
row if rows was 1 and the target table had OIDs, but OIDs system
columns are not supported anymore; therefore oid is always 0.
That tag is the status that you are seeing. There's nothing else in the CommandComplete message.
The Node Postgres client does include a rowCount member in result, but if you look at the code, you will see that it just parses it out of the string. The Java JDBC driver also parses the string.
This code works just fine (all database items updated as expected):
foreach($idMap as $menuId=>$pageId)
{
$sql = "UPDATE `menus_items` SET link = '/content/show?id=".$pageId."' WHERE id = ".$menuId."; ";
$affectedRows = Yii::app()->db->createCommand($sql)->execute();
echo $affectedRows." affected rows\n";
}
But it prints 0 affected rows for each executed query. Why?
The same effect is, when executing many rows affecting statements in one SQL query:
$sql = '';
foreach($idMap as $menuId=>$pageId)
{
$sql .= "UPDATE `menus_items` SET link = '/content/show?id=".$pageId."' WHERE id = ".$menuId."; ";
}
$affectedRows = Yii::app()->db->createCommand($sql)->execute();
echo $affectedRows." affected rows\n";
What am I missing? Docs says, that CDbCommand::execute should return number of rows affected by the execution. Does this feature work, when used inside migration?
CDbCommand::execute returns the row Count from underlying PDO interface, PDOstatement::rowCount only returns the row count of the last statement.
I had tested this within migration to be sure that migrate script is not running any other commands for cleanup etc, this is not the case, I am able to get correct row values from within and outside migration as well.
The most likely reason you are getting 0 as the value is because of the update command did not affect any rows ( i.e. the link values were already set to the correct values), UPDATE will return 0 if no change has occurred.
Perhaps you already run the migration on your test db and migrated down to test it few more times, however during the subsequent passes no update actually happened.
Note in the second scenario only the count of the last command ( a single row update will be shown even if update changes the table as PDOstatement::rowCount only returns the count for last statement executed.
I have a problem with BIRT when I try to pass multiple values from report parameter.
I'm using BIRT 2.6.2 and eclipse.
I'm trying to put multiple values from cascading parameter group last parameter "JDSuser". The parameter is allowed to have multiple values and I'm using list box.
In order to be able to do that I'm writing my sql query with where-in statement where I replace text with javascript. Otherwise BIRT sql can't get multiple values from report parameter.
My sql query is
select jamacomment.createdDate, jamacomment.scopeId,
jamacomment.commentText, jamacomment.documentId,
jamacomment.highlightQuote, jamacomment.organizationId,
jamacomment.userId,
organization.id, organization.name,
userbase.id, userbase.firstName, userbase.lastName,
userbase.organization, userbase.userName,
document.id, document.name, document.description,
user_role.userId, user_role.roleId,
role.id, role.name
from jamacomment jamacomment left join
userbase on userbase.id=jamacomment.userId
left join organization on
organization.id=jamacomment.organizationId
left join document on
document.id=jamacomment.documentId
left join user_role on
user_role.userId=userbase.id
right join role on
role.id=user_role.roleId
where jamacomment.scopeId=11
and role.name in ( 'sample grupa' )
and userbase.userName in ( 'sample' )
and my javascript code for that dataset on beforeOpen state is:
if( params["JDSuser"].value[0] != "(All Users)" ){
this.queryText=this.queryText.replaceAll('sample grupa', params["JDSgroup"]);
var users = params["JDSuser"];
//var userquery = "'";
var userquery = userquery + users.join("', '");
//userquery = userquery + "'";
this.queryText=this.queryText.replaceAll('sample', userquery);
}
I tryed many different quote variations, with this one I get no error messages, but if I choose 1 value, I get no data from database, but if I choose at least 2 values, I get the last chosen value data.
If I uncomment one of those additional quote script lines, then I get syntax error like this:
The following items have errors:
Table (id = 597):
+ An exception occurred during processing. Please see the following message for details: Failed to prepare the query execution for the
data set: Organization Cannot get the result set metadata.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: SQL statement does not return a ResultSet object. SQL error #1: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 'rudolfs.sviklis',
'sample' )' at line 25 ;
com.mysql.jdbc.exceptions.jdbc4.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
'rudolfs.sviklis', 'sample' )' at line 25
Also, I should tell you that i'm doing this by looking from working example. Everything is the same, the previous code resulted to the same syntax error, I changed it to this script which does the same.
The example is available here:
http://developer.actuate.com/community/forum/index.php?/files/file/593-default-value-all-with-multi-select-parsmeter/
If someone could give me at least a clue to what I should do that would be great.
You should always use the value property of a parameter, i.e.:
var users = params["JDSuser"].value;
It is not necessary to surround "userquery" with quotes because these quotes are already put in the SQL query arround 'sample'. Furthermore there is a mistake because userquery is not yet defined at line:
var userquery = userquery + users.join("', '");
This might introduce a string such "null" in your query. Therefore remove all references to userquery variable, just use this expression at the end:
this.queryText=this.queryText.replaceAll('sample', users.join("','"));
Notice i removed the blank space in the join expression. Finally once it works finely, you probably need to make your report input more robust by testing if the value is null:
if( params["JDSuser"].value!=null && params["JDSuser"].value[0] != "(All Users)" ){
//Do stuff...
}
I'm trying to do a SELECT COUNT(*) with Postgres.
What I need: Catch the rows affected by the query. It's a school system. If the student is not registered, do something (if).
What I tried:
$query = pg_query("SELECT COUNT(*) FROM inscritossimulado
WHERE codigo_da_escola = '".$CodEscola."'
AND codigo_do_simulado = '".$simulado."'
AND codigo_do_aluno = '".$aluno."'");
if(pg_num_rows($query) == 0)
{
echo "Error you're not registered!";
}
else
{
echo "Hello!";
}
Note: The student in question IS NOT REGISTERED, but the result is always 1 and not 0.
For some reason, when I "show" the query, the result is: "Resource id #21". But, I look many times in the table, and the user is not there.
You are counting the number of rows in the answer, and your query always returns a single line.
Your query says: return one row giving the number of students matching my criteria. If no one matches, you will get back one row with the value 0. If you have 7 people matching, you will get back one row with the value 7.
If you change your query to select * from ... you will get the right answer from pg_num_rows().
Actually, don't count at all. You don't need the count. Just check for existence, which is proven if a single row qualifies:
$query = pg_query(
'SELECT 1
FROM inscritossimulado
WHERE codigo_da_escola = $$' . $CodEscola . '$$
AND codigo_do_simulado = $$' . $simulado. '$$
AND codigo_do_aluno = $$' . $aluno . '$$
LIMIT 1');
Returns 1 row if found, else no row.
Using dollar-quoting in the SQL code, so we can use the safer and faster single quotes in PHP (I presume).
The problem with the aggregate function count() (besides being more expensive) is that it always returns a row - with the value 0 if no rows qualify.
But this still stinks. Don't use string concatenation, which is an open invitation for SQL injection. Rather use prepared statements ... Check out PDO ...
As the official documentation does not say how to do a simply "num_rows" with their system, i need some help here: How to get the amount of rows in the result set ?
Assuming:
$connection=Yii::app()->db;
$command=$connection->createCommand($sql);
This will work for insert, update and delete:
$rowCount=$command->execute();
execute(): performs a non-query SQL statement, such as INSERT, UPDATE and DELETE. If successful, it returns the number of rows that are affected by the execution.
For select, you could do the following:
$dataReader=$command->query();
This generates the CDbDataReader instance and CDbDataReader provides a rowCount property
http://www.yiiframework.com/doc/api/1.1/CDbDataReader#rowCount-detail
$rowCount = $dataReader->rowCount;
About rowCount => Returns the number of rows in the result set. Note, most DBMS may not give a meaningful count. In this case, use "SELECT COUNT(*) FROM tableName" to obtain the number of rows.
ActiveRecord has count method which can be used.
$cntCriteria = new CDbCriteria();
$cntCriteria->condition = "categoryId = :categoryId";
$cntCriteria->params[':categoryId'] = $categoryRow->categoryId;
$articleCount = Article::model()->count($cntCriteria);
There is one more way to do this. When we execute a sql query it will return the result as array only. So we can able get the count of the rows using count() function like below.
$output=User::model()->findAllBySql("select * from user");//User is a model belongs to the user table
$count_val=count($output);//$count_val has the value of number of rows in the output.