PDO MySQL case sensitive even with utf8_general_ci - pdo

I have a MySQL table that has utf8_general_ci collation and I am using PDO prepared statements to connect to it.
$conn = new PDO('mysql:host=localhost;dbname=crm;charset=utf8', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
I am not using a binary query so it is:
$stmt = $conn->prepare("SELECT * FROM primary_profile WHERE email LIKE :email");
$stmt->execute(array('email' => $email));
I do not understand why the query is not considered case insensitive and returns false if the case does not match.

You want to run the following:
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TABLE_name'
There are collation settings per field as well as per table.

Related

What does SELECT followed by a SQL command as a string mean

What does something like
SELECT 'DROP INDEX' || 'some other string'
mean?
I know usually you have the column name after the select, like SELECT first_name, but what does it mean when it is in single quotes? I believe the || means to concatenate the strings. Sorry, I'm new to this and couldn't seem to find anything about this.
EDIT: Sorry I realized my question was not very clear. I meant to ask what does it mean if the SELECT was followed by a SQL command in single quotes? Would it be any different? Would it also just create a column with DROP INDEX as the header? Something like
SELECT 'DROP INDEX' || 'some other string'
FROM ...
WHERE...
The idea here is to generate SQL statements from database metadata so that you can later execute them as a script. That is a two-step process: first you run an SQL statement that generates SQL statements, then you execute those SQL statements (unless you are using psql, where \gexec can do that in a single step).
But if you use the string concatenation operator || to construct the statements, you run the risk of SQL injection.
For example, to delete all tables in a schema, you could generate a script with
SELECT 'DROP TABLE ' || table_schema || '.' || table_name
FROM information_schema.tables
WHERE table_schema = 'my_schema';
Now if there happens to be a table called My-Table, that script would fail, since that is not a standard conforming SQL identifier and would have to be quoted.
And that is also not safe:
SELECT 'DROP TABLE "' || table_schema || '"."' || table_name || '"'
FROM information_schema.tables
WHERE table_schema = 'my_schema';
because there could be a table called silly"name.
By crafting tables with names like existing_table"; DROP TABLE "important, you could abuse such a statement to create havoc in the database.
Avoid string concatenation and use format:
SELECT format('DROP TABLE %I.%I', table_schema, table_name)
FROM information_schema.tables
WHERE table_schema = 'my_schema';
Selecting a string will return the string value.
SELECT 'string here'
Will return string here
|| is short hand for concatenation.
SELECT 'string' || ' here'
Will return string here.
EDIT:
Selecting a SQL command will return the SQL command in the message. This is often done when creating dynamic SQL and wanting to validate the SQL command before executing it. If you put a SQL command in the #sql NVARCHAR(max) variable, you can SELECT #sql to return the query or EXEC sp_executesql #sql to execute the SQL command (SQL Server syntax).
SELECT name, 'is a human' AS Note FROM people
The result would be a table with 2 colums: Name and Note.
Name would be the person's name and Note would always say 'is a human'.
|| is the logical OR operator.
Links:
http://www.geeksengine.com/database/basic-select/literal-character-strings.php
http://www.geeksengine.com/database/basic-select/using-logical-operators.php
Edit:
It was not the question but DROP INDEX is a SQL command: https://www.w3schools.com/SQL/sql_ref_drop_index.asp

Get all table names of a particular database by SQL query?

I am working on application which can deal with multiple database servers like "MySQL" and "MS SQL Server".
I want to get tables' names of a particular database using a general query which should suitable for all database types. I have tried following:
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE'
But it is giving table names of all databases of a particular server but I want to get tables names of selected database only. How can I restrict this query to get tables of a particular database?
Probably due to the way different sql dbms deal with schemas.
Try the following
For SQL Server:
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='dbName'
For MySQL:
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA='dbName'
For Oracle I think the equivalent would be to use DBA_TABLES.
Stolen from here:
USE YOURDBNAME
GO
SELECT *
FROM sys.Tables
GO
The following query will select all of the Tables in the database named DBName:
USE DBName
GO
SELECT *
FROM sys.Tables
GO
Just put the DATABASE NAME in front of INFORMATION_SCHEMA.TABLES:
select table_name from YOUR_DATABASE.INFORMATION_SCHEMA.TABLES where TABLE_TYPE = 'BASE TABLE'
USE DBName;
SELECT * FROM sys.Tables;
We can deal without GO in-place of you can use semicolon ;.
In mysql, use:
SHOW TABLES;
After selecting the DB with:
USE db_name
In order if someone would like to list all tables within specific database without using the "use" keyword:
SELECT TABLE_NAME FROM databasename.INFORMATION_SCHEMA.TABLES
This works Fine
SELECT
*
FROM
information_schema.tables;
I did not see this answer but hey this is what I do :
SELECT name FROM databaseName.sys.Tables;
To select the database query below :
use DatabaseName
Now
SELECT * FROM INFORMATION_SCHEMA.TABLES
Now you can see the created tables below in console .
PFA.
For Mysql you can do simple. SHOW TABLES;
select * from sys.tables
order by schema_id --comments: order by 'schema_id' to get the 'tables' in 'object explorer order'
go
In our Oracle DB (PL/SQL) below code working to get the list of all exists tables in our DB.
select * from tab;
and
select table_name from tabs;
both are working. let's try and find yours.
SELECT TABLE_NAME
FROM your_database_name.INFORMATION_SCHEMA.TABLES
ORDER BY TABLE_NAME;
Exec sp_MSforeachtable 'Select ''?'''
USE dbName;
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE (TABLE_SCHEMA = 'dbName' OR TABLE_SCHEMA = 'schemaName')
ORDER BY TABLE_NAME
If you are working with multiple schemata on an MS SQL server, then SELECT-ing TABLE_NAME without also simultaneously selecting TABLE_SCHEMA might be of limited benefit, so I have assumed we are interested in the tables belonging to a known schema when using MS SQL Server.
I have tested the query above with SQL Server Management Studio using an SQL Server database of mine and with MySQL Workbench using a MySQL database, and in both cases it gives the table names.
The query bodges Michael Baylon's two different queries into one that can then run on either database type. The first part of the WHERE clause works on MySQL databases and the second part (after the OR) works on MS SQL Server databases. It is ugly and logically a little incorrect as it supposes that there is no undesired schema with the same name as the database. This might help someone who is looking for one single query that can run on either database server.
UPDATE FOR THE LATEST VERSION OF MSSQL SERVER (17.7)
SELECT name FROM sys.Tables WHERE type_desc = 'USER_TABLE'
Or SELECT * for get all columns.
Yes oracle is :
select * from user_tables
That is if you only want objects owned by the logged in user/schema otherwise you can use all_tables or dba_tables which includes system tables.
Building from Michael Baylon's answer, I needed a list which also included schema information and this is how I modified his query.
SELECT TABLE_SCHEMA + '.' + TABLE_NAME as 'Schema.Table'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG = 'dbName'
ORDER BY TABLE_SCHEMA, TABLE_NAME
Simply get all improtanat information with this below SQL in Mysql
SELECT t.TABLE_NAME , t.ENGINE , t.TABLE_ROWS ,t.AVG_ROW_LENGTH,
t.INDEX_LENGTH FROM
INFORMATION_SCHEMA.TABLES as t where t.TABLE_SCHEMA = 'YOURTABLENAMEHERE'
order by t.TABLE_NAME ASC limit 10000;
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME
for postgres it will be:
SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'your_schema' -- probably public

SQL: how to know if a field has "Allow nulls" checked or not checked by SQL command

I want to know which table's field are required or not required so I have to get "Allow nulls" state. How to do that?
I will assume you are talking about SQL Server.
There is a table, INFORMATION_SCHEMA.COLUMNS, that contains meta-data about the columns in the database.
You can do this:
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
IS_NULLABLE gives you the "Allow Nulls" value used in the designer.
If your in MySQL use the sql command
DESCRIBE Table;
Where table is the name of the table you want to examine
Try this (SQL Server)
select sysobjects.name, syscolumns.name, syscolumns.isnullable
from sysobjects join syscolumns
on sysobjects.id = syscolumns.id
and sysobjects.xtype = 'U'
and sysobjects.name = 'your table name'

How to determine if a field is set to not null?

I have an existing program deployed where some customer databases have a field set to not null, while others are nullable. I need to run a patch to correct the database so that the column is nullable but do not need to run it against all databases, just ones where it is incorrect. Is there a simple method that can be used in SQL Server to perform this check? Preferably something that can be run as part of a SQL script.
Look into the INFORMATION_SCHEMA views. For example:
SELECT
IS_NULLABLE
FROM
My_DB.INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'dbo' AND
TABLE_NAME = 'My_Table' AND
COLUMN_NAME = 'My_Column'
IS_NULLABLE will be either "YES" or "NO".
select Table_Name, Column_Name, Is_Nullable
from information_schema.columns
Will get you that info
select isnullable from syscolumns where name = 'status'

What is the SQL command to return the field names of a table?

Say I have a table called myTable. What is the SQL command to return all of the field names of this table? If the answer is database specific then I need SQL Server right now but would be interested in seeing the solution for other database systems as well.
MySQL 3 and 4 (and 5):
desc tablename
which is an alias for
show fields from tablename
SQL Server (from 2000) and MySQL 5:
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'tablename'
Completing the answer: like people below have said, in SQL Server you can also use the stored procedure sp_help
exec sp_help 'tablename'
SQL-92 standard defines INFORMATION_SCHEMA which conforming rdbms's like MS SQL Server support. The following works for MS SQL Server 2000/2005/2008 and MySql 5 and above
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'myTable'
MS SQl Server Specific:
exec sp_help 'myTable'
This solution returns several result sets within which is the information you desire, where as the former gives you exactly what you want.
Also just for completeness you can query the sys tables directly. This is not recommended as the schema can change between versions of SQL Server and INFORMATION_SCHEMA is a layer of abstraction above these tables. But here it is anyway for SQL Server 2000
select [name] from dbo.syscolumns where id = object_id(N'[dbo].[myTable]')
You can use the provided system views to do this:
eg
select * from INFORMATION_SCHEMA.COLUMNS
where table_name = '[table name]'
alternatively, you can use the system proc sp_help
eg
sp_help '[table name]'
PostgreSQL understands the
select column_name from information_schema.columns where table_name = 'myTable'
syntax. If you're working in the psql shell, you can also use
\d myTable
for a description (columns, and their datatypes and constraints)
For those looking for an answer in Oracle:
SELECT column_name FROM user_tab_columns WHERE table_name = 'TABLENAME'
Just for completeness, since MySQL and Postgres have already been mentioned: With SQLite, use "pragma table_info()"
sqlite> pragma table_info('table_name');
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 99 1
1 name 0 0
This is also MySQL Specific:
show fields from [tablename];
this doesnt just show the table names but it also pulls out all the info about the fields.
In Sybase SQL Anywhere, the columns and table information are stored separately, so you need a join:
select c.column_name from systabcol c
key join systab t on t.table_id=c.table_id
where t.table_name='tablename'
MySQL is the same:
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'tablename'
If you just want the column names, then
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'tablename'
On MS SQL Server, for more information on the table such as the types of the columns, use
sp_help 'tablename'
For IBM DB2 (will double check this on Monday to be sure.)
SELECT TABNAME,COLNAME from SYSCAT.COLUMNS where TABNAME='MYTABLE'
MySQL
describe tablename
select COLUMN_NAME1,COLUMN_NAME2 from SCHEMA_NAME.TABLE_NAME
where TABLE_NAME.COLUMN_NAME = 'COLUMN_NAME1';