How to escape parameter in like sql query using active record? - sql

Have query with parentesis:
SELECT *
FROM users
WHERE company_id = 1 AND (
name LIKE "%smith%" OR
last_name LIKE "%smith%"
)
But in codeigniter have:
$query_members = $this->db
->select('users.*')
->from('users')
->like(array('users.names' => $search))
->or_like(array('users.last_name' => $search))
->where(array('users.company_id' => 1));
This generate:
SELECT *
FROM users
WHERE
name LIKE '%smith%' OR
last_name LIKE '%smith%' AND
company_id = 1;
And does not works, i need ((a or b) and c), not (a or b and c). I found solution here: Codeigniter parentheses in dynamic Active Record query but the variable is escaped with full quotes, i need escape with "%" pre and pos value. I have this:
$search_escaped = $this->db->escape($search);
$query_members = $this->db
->select('users.*')
->from('users')
->where('(users.names LIKE "%'.$search_escaped.'%" OR users.last_name LIKE "%'.$search_escaped.'%")')
->where(array('members.company_id' => (int)$company_id));
But the query add bad quotes:
SELECT `users`.*
FROM `users`
WHERE (users.names LIKE "%'smith'%" OR users.last_name LIKE "%'smith'%")
AND `members`.`company_id` = 2
The "%'smith'%" is bad quoted. How I can solve this by using active record of codeigniter 3.0.0?

Related

SQL statement with multiple keywords in string in LIKE statement

I am trying to pull data based on multiple keywords from the same column.
Currently I have a SQL statement that works like this.
SELECT *
FROM Customers
WHERE CustomerName LIKE 'a%'
OR CustomerName LIKE '_r%'
OR CustomerName LIKE 'si%';
That works fine. What I am trying to achieve is to pass the keywords c("a", "_r", "si") as a vector. Like this:
keywords <- c("a", "_r", "si")
SELECT *
FROM Customers
WHERE CustomerName LIKE '%' + keywords + '%';
That did not work. How do I submit a variable with a bunch of keywords into the like statement?
Use sprintf and paste/collapse= . Within a sprintf format %s is replaced with the next argument and %% means %.
keywords <- c("a", "_r", "si")
sql <- keywords |>
sprintf(fmt = "CustomerName LIKE '%%%s%%'") |>
paste(collapse = " OR \n") |>
sprintf(fmt = "SELECT *
FROM Customers
WHERE %s")
cat(sql, "\n")
giving:
SELECT *
FROM Customers
WHERE CustomerName LIKE '%a%' OR
CustomerName LIKE '%_r%' OR
CustomerName LIKE '%si%'
Just another option using string_split() and a JOIN
Example
DECLARE #Find VARCHAR(max) = ('a%,_r%,si%')
Select Distinct A.*
From Customers A
Join string_split(#Find,',') B
on CustomerName like B.value

Postgresql SELECT without hardcoding item

I have a simple PostgreSql query that looks like:
$params = array();
if ($audienceId === x) {
// all teachers
$pullRecipients = $db -> prepare(
"SELECT email FROM app.employees WHERE emp_cat_id = 1 AND active is true");
}
$pullRecipients -> execute($params);
I'm running the queries based on a drop down select, so that if for example the user selects TEACHERS, the above query is run. How can I select for instance the emp_cat_id or even the category name TEACHERS without hard coding them in the query?
change statement to something like
SELECT email
FROM app.employees
WHERE emp_cat_id = ? AND active IS true
and make sure your $params is equal to something like array($POST["drop-down_value])
and if you want to allow text value - use join, something like:
SELECT email
FROM app.employees
WHERE emp_cat_id = (SELECT id FROM emp_cat WHERE name = ?)
AND active IS true

Like statement across multiple columns in SQL

I'm trying to query a like statement across multiple columns. I have the following search terms:
'dog'
'cat'
'rabbit'
'gerbil'
'guinea pig'
'hamster'
and I need search for these terms or terms LIKE these in the 'animals' table which has about 40 different columns. I am aware I can do the like statement by doing
Select * from animals where [animalscolumn] like ('%dog%') or like ('%cat%') or like ('%gerbil%') or like ('%hamster%') or like ('%guinea pig%')
However the 'animalscolumn' isn't the only column I need to run the 'LIKE' statement across. I have to search for these terms in about 40 columns. Would anyone happen to know how? Thanks!
multiple like statements can not be used with or directly. You have to use column name for each like statement.
Use multiple like as mentioned below.
Select *
from animals
where
(
[animalscolumn] like ('%dog%') or
[animalscolumn] like ('%cat%') or
[animalscolumn] like ('%gerbil%') or
[animalscolumn] like ('%hamster%') or
[animalscolumn] like ('%guinea pig%')
)
If you want to find a set of number you can use IN
SELECT *
FROM tableName
WHERE columnId IN (154,156,133,157,119)
$sql = "SELECT * from like1 WHERE tutorial_author LIKE '$apply'
OR
tutorial_title LIKE '$apply'";
if($mode == 'search_contact'){
// $prefix='%';
$apply=$dataObj['search'];
$data = array();
// $sql = "SELECT * from add_contact WHERE tutorial_author OR tutorial_title LIKE '$apply'";
$sql = "SELECT * from add_contact WHERE
first_name LIKE '%$apply%'
OR
last_name LIKE '%$apply%'
OR
title LIKE '%$apply%'
OR
company LIKE '%$apply%'
OR
address LIKE '%$apply%'";
$result = $myConnection->query($sql);
if ($result->num_rows > 0) {
// print_r($result->fetch_assoc());
while($row = $result->fetch_assoc()) {
$row['user_image'] = site_url.upload_dir.$row['image'];
// print_r($row);
$data[]=$row;
}
$array = array('status'=>true, 'message'=> 'contacts fetched successfully', 'data'=> $data);
echo json_encode($array);
exit;
} else {
$array = array('status'=>false, 'message'=> "No contacts available" );
echo json_encode($array);
exit;
}
}
Select * from cscart_users
where status like '%a' and user_type like '%c' and firstname like '%az%';
Select * from cscart_users where status like '%a' and user_type like '%c'and firstname like'%az%';
syntax:
select * from tablename where columnname like'%b' and columnname2 like '%g';
Here is an example of a SQL Server stored procedure that takes a parameter.
CREATE PROCEDURE [dbo].sp_SearchMultiple #SearchTerm nvarchar(256)
AS
BEGIN
SET #SearchTerm = '%' + #SearchTerm + '%'
SELECT TOP 100
id, col1, col2, col3
FROM
asset_f
WHERE
col1 LIKE #SearchTerm OR col2 LIKE #SearchTerm OR col3 LIKE #SearchTerm
ORDER BY
id ASC
END

Rails query join on regex

This is a query run very infrequently (as admin), and it's not worth indexing/ using up RAM with sphinx.
So, with the variables set up something like this:
fn, ln, em = 'John', 'Smith', 'johnsmith#gmail.com'
The query is something like this:
profiles = Profile.joins(:user).where(:users=>{"email" => em}).
where("first_name LIKE '%#{fn}%' AND last_name LIKE '%#{ln}%'")
Except that I want the email to accept a substring (e.g. if em == 'th#gm', then it should match 'johnsmith#gmail.com'). How do you write this to do a join selecting only those users with a variable matching a regex?
(I got my inspiration from here):
Have you tried something like:
profiles = Profile.joins(:user).where("first_name LIKE ? AND last_name LIKE ?", "%#{fn}%", "%#{ln}%")
profiles.select{|p| p.user.email =~ /#{em}/}

Selecting from a table where field = this and value = that

I have a mysql table that looks something like this:
Row 1:
'visitor_input_id' => int 1
'name' => string 'country'
'value' => string 'Canada'
Row 2:
'visitor_input_id' => int 1
'name' => string 'province'
'value' => string 'Alberta'
Row 3:
'visitor_input_id' => int 1
'name' => string 'first_name'
'value' => string 'Jim'
The problem is that I need to be able to filter it so that a user can generate reports using this:
filter 1:
'field_name' => string 'country'
'field_operator' => string '='
'field_value' => string 'Canada'
filter 2:
'field_name' => string 'province'
'field_operator' => string '!='
'field_value' => string 'Alberta'
filter 3:
'field_name' => string 'first_name'
'field_operator' => string '%LIKE%'
'field_value' => string 'Jim'
I am not really sure what the query would look like to be able to select from this using the filters. Any suggestions? (Unfortunately, creating a new table to store the data more sanely is not really feasible at this time because it is already full of user data)
I think it would look something like this:
if(field_name = 'province' THEN ADD WHERE field_value != 'Alberta')
if(field_name = 'country' THEN ADD WHERE field_value = 'Canada')
if(field_name = 'first_name' THEN ADD WHERE field_value LIKE '%jim%')
but I am not sure how that would work...
Turns out that this seems to work:
SELECT * FROM visitor_fields
INNER JOIN visitor_inputs ON (visitor_inputs.input_id = visitor_fields.input_id)
INNER JOIN visitor_fields as filter_0
ON (filter_0.input_id=visitor_inputs.input_id
AND filter_0.field_name = 'province'
AND filter_0.field_value != 'Alberta')
INNER JOIN visitor_fields as filter_1
ON (filter_1.input_id=visitor_inputs.input_id
AND filter_1.field_name = 'country'
AND filter_1.field_value = 'Canada')
INNER JOIN visitor_fields as filter_2
ON (filter_2.input_id=visitor_inputs.input_id
AND filter_2.field_name = 'first_name'
AND filter_2.field_value LIKE '%jim%')
I know you say creating a new table with a better schema isn't feasible, but restructuring the data would make it more efficient to query and easier to work with. Just create a new table (called visitor in my example). Then select from the old table to populate the new visitor table.
vistor
----------------
vistor_id
firstname
province
country
You could loop through the statement below with any scripting language (PHP, TSQL, whatever scripting language you're most comfortable with). Just get a list of all vistor_id's and loop through them with the sql below, replacing the x with the visitor_id.
INSERT INTO visitor (visitor_id, name, province, country) VALUES X,
(SELECT value FROM old_table WHERE name='first_name' AND vistor_id = x),
(SELECT value FROM old_table WHERE name='province' AND vistor_id = x),
(SELECT value FROM old_table WHERE name='country' AND vistor_id = x);
This will produce a table where all a visitor's data is on a single row.
Are you able to create an SQL string and then execute it? The string would look like this:
SELECT * FROM yourtable
WHERE (name='country' AND value='Canada') AND
(name='province' AND value!='Alberta') AND
(name='first_name' AND value LIKE '%jim%)
EDIT:
I see. Multiple records. So try joining them. This is not correct SQL syntax but should look similar:
SELECT * FROM
(SELECT * FROM yourtable WHERE (name='country' AND value='Canada'))
JOIN on visitor_input_id
(SELECT * FROM yourtable WHERE (name='province' AND value!='Alberta'))
JOIN on visitor_input_id
(SELECT * FROM yourtable WHERE (name='first_name' AND value LIKE '%jim%))