Store procedure select all fields from One table using join - linq-to-sql

I am very frustrated from linq to sql when dealing with many to many relationship with the skip extension. It doesn't allow me to use joinned queries. Not sure it is the case for SQL server 2005 but I am currently using SQL Server 2000.
Now I consider to write a store procedure to fetch a table that is matched by two tables e.g. Album_Photo (Album->Album_Photo<-Photo) and Photo table and only want the Photos data so I match the Album's ID with Album_Photo and use that ID to match the photo. In the store procedure I am just fetch all the joinned data. After that in the linq to sql, I create a new Album object.
e.g.
var albums = (from r in result
where (modifier_id == r.ModifierID || user_id == r.UserID)
select new Album() {
Name = r.Name,
UserID = r.UserID,
ModifierID = r.ModifierID,
ID = r.ID,
DateCreated = r.DateCreated,
Description = r.Description,
Filename = r.Filename
}).AsQueryable();
I used the AsQueryable to get the result as a IQueryable rather than IEnumerable. Later I want to do something with the collection, it gives me this error:
System.InvalidOperationException: The query results cannot be enumerated more than once.

It sounds like you have a situation where the query has already executed by the time you are want to filter it later in your code.
Can you do something like...
var albums = (blah blah blah).AsQueryable().Where(filterClause) when you have enough info to process
what happens if you try albums.where(filter) later on in the code? Is this what you are trying?

Related

return result from table that not existed on another table in codeignator

I've constructed two tables: one to list the services and another to link the service to each department.
Table 1 contains the columns [s id,s name]. [s_id,s_name].
-- The Services table, records all services for all departments. [1,Install Windows 10],[2,print Payslip].
Table 2 : services_assignments consist of columns [ss_id,ss_s_id_ss_d_id].
-- services_assignments matching the services with departments.
I need to return the service that "NOT" matched for the department example.
i tried to use JOIN with Where conditions in selection but not result as the following code.
function get_services_for_assign(){ // for assigmnets
$this->db->select('*');
$this->db->from('services');
if($this->uri->segment('2')) {
$this->db->join('services_assignments','services.sr_id = services_assignments.ss_s_id','left');
$this->db->where_not_in('services_assignments.ss_d_id',$this->uri->segment('2'));
}
//$this->db->where('sr_display','1');
$data=$this->db->get();
return $data->result();
}
On the other hand, I attempted to write it manually as seen below.
function get_services_for_assign(){ // for assigmnets
$dep=$this->uri->segment('2');
$query = "SELECT sr.sr_id FROM services AS sr WHERE sr.sr_id = (SELECT sa.ss_s_id FROM services_assignments AS sa WHERE sa.ss_d_id = 1)";
$this->db->query($query);
$data=$this->db->get();
return $data->result();
}
and I encountered the following error; I discovered numerous results that were similar to my problem, but I couldn't solve it.
A Database Error Occurred
Error Number: 1096
No tables used
SELECT *
Filename: C:/xampp/htdocs/townteam/system/database/DB_driver.php
Line Number: 691
I need your help to return the results services that were not used by the other department.
You have not stated which version of CodeIgniter you are using or what the expected behaviour is when no department id is passed.
This should work in both CI3 and CI4. If using CI4, you should probably use prepared statements. I could not find documentation on passing parameters into a multi-condition join with CI so I have written the query out in full.
$sql = <<<'SQL'
SELECT s.*
FROM services s
LEFT JOIN services_assignments sa
ON s.sr_id = sa.ss_s_id
AND sa.ss_d_id = ?
WHERE sa.ss_s_id IS NULL
AND s.sr_display = 1
SQL;
$this->db->query($sql, [$this->uri->segment('2')]);

How to make where condition always be true with field =?

I have a sql statement follow:
select * from table where id = ?
Now, problem is, l don't know whether front end will send me the value of id, if it did, this sql seem like id = 1, and if not, sql should be like id = true(fake code) to find all data
How could I write my sql?
Or, It is fundamentally wrong?
This is normally handled by using logic such as this:
select *
from table
where id = ? or ? is null;
If you don't want to pass the parameter twice or use named parameters:
select t.*
from table t cross join
(select ? as param) params
where id = params.param or params.param is null;
If you want to return all ids if the passed-in value does not exist:
select t.*
from table t
where id = ? or
not exists (select 1 from table t2 where t2.id = ?);
What you can try doing is in your code, write a function for fetching a specific record, and another function for fetching all the records from your table.
In PHP, it could be something like:
// Fetching a specific record
function getCustomerRecord($customerId) {
// Code to fetch specific record from database
}
// Fetching all records
function getAllCustomerRecords() {
// Code to fetch all records from database
}
In the function where you process requests received, check first if a value for id was passed. If a value for id was passed, call the function to fetch a specific record, making sure to pass along the value you received as an argument. Otherwise, call the function to fetch all the records from your table.
You can try doing this to get your right sql statement in PHP
function GetSqlStatement($id){
return $sql = "select * from table where id = ".$id.";";
}

Is it OK to all values in a column of a table without limit?

I'm trying to get the product ids of the product used by a customer with the query,
select
v.product_id
from
TableA as v
join
TableB as f
on
v.id = f.id
where
f.product_name = "<some_name>"
and
f.customer_id = "<id>"
Note : product_id is the primary key of TableA
There could be too many rows matching the criteria and in the worst case it could be the entire value of a column in a table.
Is this OK to execute the query without any limit operator? How could I get to know the query which I run is safe (ie; produces no OOM kind of issues) when the result set obtained is too large?
EDIT
This is my getMySQLConnection part of my code
String url = "jdbc:mysql://" + host + ":" + port + "/" + dbname;
String clazz = "org.gjt.mm.mysql.Driver";
Driver driver = (Driver) Class.forName(clazz).newInstance();
DriverManager.registerDriver(driver);
return DriverManager.getConnection(url, user, pwd);
Some thing like a GET request which could be able to transfer around 2-8kb (as far as I remember). what is the maximum size of data (ie' the result set data) that could be transferred with this url connection?
You should not use limit in the query. otherwise, you will not get the whole product list.
and the worst case happens only if there is only one customer on your site.
It depends what the purpose of the query is.
Do you need to evaluate EVERY row which meets that query criteria? Is so then you would need to SELECT without limit.
However if you do not need every row as in a paginated report, you could use LIMIT MAX MIN.

Building an entity join LINQ query

I have the following table strutucture and am accessing them by using MySQL Entity Framework:
Table Users
- Id
- Name
Table Subscriptions
- Id
- Id_User
- Id_Course
Table Courses
- Id
- Name
What I would like and am having a hard time to do so is building a link query for all users that returns a list with each entry containing:
User Id;
User name;
Concat string separated by comma with all courses for the user or 'no courses' string if none.
This list should be filtered by a part of users name.
I've started to build the code but can't finish it:
var Model db = new Model();
var list = from user in db.Users
join ???
where user.Name.Contains(filter.Trim())
select new { Name = user.Name, Id = user.Id, ???}
Can anyone help me please ?
You should use navigation properties (like User.Subscriptions) for this. Depending on how you created the model they may already be there, else you first should add them.
var query = from u in db.Users
where user.Name.Contains(filter) // trim the filter value first
select new
{
u.Name,
u.Id,
Courses = u.Subscriptions.Select(s => s.Course.Name)
};
var result = query.AsEnumerable()
.Select(q => new
{
q.Name,
q.Id
Courses = string.Join(", ", q.Courses)
};
The reason for doing this in two phases is that string.Join can't directly be used in an EF LINQ expression (can't be turned into SQL) so it must be done in memory (i.e. after an AsEnumerable).
But still it may be efficient to do a projection first (the first part), otherwise too much data may be fetched from the database.

Need to convert an array to Integer for a MySQL query in a Rails API

I have a piece of code which fetches the list of ids of users I follow.
#followed = current_user.followed_user_ids
It gives me a result like this [11,3,24,42]
I need to add these to NOT IN mysql query.
Currently, I am getting NOT IN ([11,3,24,42]) which is throwing an error. I need NOT IN (11,3,24,42)
This is a part of a find_by_sql statement, so using where.not is not possible for me in this point.
In rails 4:
#followed = current_user.followed_user_ids # #followed = [11,3,24,42]
#not_followed = User.where.not(id: #followed)
This should generate something like select * from users where id not in (11,3,24,42)
As you comment, you are using find_by_slq (and that is available in all rails versions). Then you could use the join method:
query = "select * from users where id not in (#{#followed.join(',')})"
This would raise mysql errors if #followed is blank, the resulting query would be
select * from users where id not in ()
To solve this whiout specifiying aditional if statements to your code, you can use:
query = "select * from users where id not in (0#{#followed.join(',')})"
Your normal queries would be like:
select * from users where id not in (01,2,3,4)
but if the array is blank then would result in
select * from users where id not in (0)
which is a still valid sql statement and is delivering no results (which might be the expected situation in your scenario).
you can do something like:
#followed = [11,3,24,42]
User.where('id not in (?)', #followed)