Sql Select - Total Rows Returned - sql

Using the database/sql package and drivers for Postgres and Mysql I want to achieve the following. I want to be able to Select one row and know that there is either zero rows, one row, or more than one row. the QueryRow function does not achieve that, because as far as I can ascertain, it will return one row without error regardless of if there is more than one row. For my situation, more than one row may be an error, and I want to know about it. I want to create a general function to do this.I looked at creating a function that uses the Query function, but I do not know how to return the first row if there is more than one row. I want to return the fact that there is more than one row, but I also want to return the first row. To determine that there is more than one row, I have to do a Next, and that overwrites the first row. Obviously I can achieve this without creating a general function, but I want a function to do it because I need to do this in a number of placesCould someone please explain to me how to achieve this. IE. To return the first row from a function when a successful Next has been done or the Next returned nothing.

I'm using both database/sql & MySQLDriver to achieve this. You can download MySQLDriver at https://github.com/go-sql-driver/ .
I wrote execQuery function myself to get one or more rows from database. It's based on MySQL but I think it can also used to Postgres with similar implement.
Assume you have a DB table named test, and have rows named id, name, age.
Code:
var db *sql.DB // it should be initialized by "sql.Open()"
func execQuery(SQL string, args ...interface{}) (rows *sql.Rows, is_succeed bool) {
rows, err := db.Query(SQL, args...)
var ret bool
if err == nil && rows != nil { // if DB query error rows will be nil, it will return false
ret = true
} else {
ret = false
}
return rows, ret
}
Usage:
var name, age string
rows, is_succeed = execQuery("SELECT `name`, `age` FROM `test` WHERE `id` = ?", "123")
if !is_succeed {
// error
return
}
for rows.Next() { // if have zero result rows, this for route won't execute
err := rows.Scan(&name, &age)
// check if has error & do something
}
If you want to know how much rows returned, just add a counter in for route, use SQL can also achieve this.
sql.Rows likes a list structure, rows *sql.Rows points on first row of returned rows. Use rows.Next() to traverse every rows. I think that's what you've asked.
If you really want to know rows count very often, using a cache mechanic like memcacheDB or Redis or just implement a simple counter yourself can help you solve the problem.

Related

Sqlboiler get only the desired columns

I am trying to follow the examples in sqlboiler (https://github.com/volatiletech/sqlboiler). But couldn't find a way to get just the columns queried in the select statement?
users, err := models.Users(
Select("id", "name"),
Where("age > ?", 30),
).All(ctx, db)
In this example, .All returns entire tuple containing empty/nil values of columns not queried. I was wondering if there is a way to return a map/list (or any relevant data structure/format) of just the queried columns. Thanks!
You get all the fields, because you get instances of models.User, which have all the fields, you want them or not.
One thing you can do is write your own cut-down User struct, and bind to that.
type LiteUser struct {
ID int `boil:"id"`
Name string `boil:"name"`
}
var users []*LiteUser
err := models.Users(
Select("id", "name"),
Where("age > ?", 30),
).Bind(ctx, db, &users)

sql.eachRow only adds the last record into a list

Good day, I'm trying to add all the users from my db to a list and print it out in a frame. But the problem is that I am only retrieving the LAST record of the users table. The others are being ignored. Here's my code
table(selectionMode: ListSelectionModel.SINGLE_SELECTION){
sql.eachRow("select * from users"){row->
println row;
def staffList = []
staffList.add(uname:row.uname,pwd:row.pwd);
tableModel(list : staffList){
closureColumn(header:'Username',read:{row1 -> return row1.uname})
closureColumn(header:'Password',read:{row1 -> return row1.pwd})
}
I think the problem is that you have redefined the staffList array within the loop. Move that to before, and you may have better results.

GO: Obtain various query results in if else block based on parameters number

I am using go-mysql-driver to make queries to my database.
I have a function In which I am passing id and warehouseId.
Now I am modifying my mysql query based on if warehouseId value is 0 or not.
The problem is the parameters that I pass in db.Query().
Following is my mysql query where I am appending additional query if warehouseId is not 0.
query := "select id,description from offers inner join offer_entities on offers.id = offer_entities.offer_id where offer_entities.entity_id = ?"
if warehouseId != 0 {
query += `and offer_entities.warehouse_id = ? `
}
query += `group by offer_id`
I parse it like this:
if warehouseId != 0 {
rows, err := db.Query(query, variantId, warehouseId)
} else {
rows, err := db.Query(query, variantId)
}
However, the problem is when I run it, I get an error undefined: rows. I know that it is because rows should be defined outside the if-else conditions. But I don't understand how to define rows outside if-else or
If there is any other way I could achieve my requirements.
How should I tackle this problem.
Thanks in advance.
the problem is because of variables are defined in the scope in which they are declared.
The difference between = and := is that = is just assignment and := is used for assignment and declaration
for example
rows := 1
//it basically means
var rows int
rows = 1
what you want is to declare rows outside the if-else and then use them, will solve the problem.
Scope visibility
Each block has itself visibility scope. A general rule is visible from inner, invisible from outer. It means you can see variables from superior scope in subject scope but not vise versa.
I believe you use rows declared in if statement out of the block, so it doesn't exist there.
var err error
var rows string
if warehouseId != 0 {
rows, err := db.Query(query, variantId, warehouseId)
} else {
rows, err := db.Query(query, variantId)
}
fmt.Println(rows) // It is now possible to use `rows` outside of the block
Declaration styles
var name <type> is a common declaration way. The variable with typed nil value will be declared.
name := <value of type> is a short declaration form. It will declare a variable of a type and assign a value to it at the same time. Allowed only in functions.

num_rows in postgres always return 1

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 ...

Yii Framework: How to get the num_rows?

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.