Is it possible to check if a (MySQL) database exists after having made a connection.
I know how to check if a table exists in a DB, but I need to check if the DB exists. If not I have to call another piece of code to create it and populate it.
I know this all sounds somewhat inelegant - this is a quick and dirty app.
SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'DBName'
If you just need to know if a db exists so you won't get an error when you try to create it, simply use (From here):
CREATE DATABASE IF NOT EXISTS DBName;
A simple way to check if a database exists is:
SHOW DATABASES LIKE 'dbname';
If database with the name 'dbname' doesn't exist, you get an empty set. If it does exist, you get one row.
From the shell like bash
if [[ ! -z "`mysql -qfsBe "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='db'" 2>&1`" ]];
then
echo "DATABASE ALREADY EXISTS"
else
echo "DATABASE DOES NOT EXIST"
fi
If you are looking for a php script see below.
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Not connected : ' . mysql_error());
}
// make foo the current db
$db_selected = mysql_select_db('foo', $link);
if (!$db_selected) {
die ('Cannot use foo : ' . mysql_error());
}
A very simple BASH-one-liner:
mysqlshow | grep dbname
Here is a bash function for checking if a database exists:
function does_db_exist {
local db="${1}"
local output=$(mysql -s -N -e "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '${db}'" information_schema)
if [[ -z "${output}" ]]; then
return 1 # does not exist
else
return 0 # exists
fi
}
Another alternative is to just try to use the database. Note that this checks permission as well:
if mysql "${db}" >/dev/null 2>&1 </dev/null
then
echo "${db} exists (and I have permission to access it)"
else
echo "${db} does not exist (or I do not have permission to access it)"
fi
For those who use php with mysqli then this is my solution. I know the answer has already been answered, but I thought it would be helpful to have the answer as a mysqli prepared statement too.
$db = new mysqli('localhost',username,password);
$database="somedatabase";
$query="SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME=?";
$stmt = $db->prepare($query);
$stmt->bind_param('s',$database);
$stmt->execute();
$stmt->bind_result($data);
if($stmt->fetch())
{
echo "Database exists.";
}
else
{
echo"Database does not exist!!!";
}
$stmt->close();
A great way to check if a database exists in PHP is:
$mysql = mysql_connect("<your host>", "root", "");
if (mysql_select_db($mysql, '<your db name>')) {
echo "Database exists";
} else {
echo "Database does not exist";
}
That is the method that I always use.
Using bash:
if [ "`mysql -u'USER' -p'PASSWORD' -se'USE $DATABASE_NAME;' 2>&1`" == "" ]; then
echo $DATABASE_NAME exist
else
echo $DATABASE_NAME doesn't exist
fi
CREATE SCHEMA IF NOT EXISTS `demodb` DEFAULT CHARACTER SET utf8 ;
SELECT IF('database_name' IN(SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA), 1, 0) AS found;
Here's my way of doing it inside a bash script:
#!/bin/sh
DATABASE_USER=*****
DATABASE_PWD=*****
DATABASE_NAME=my_database
if mysql -u$DATABASE_USER -p$DATABASE_PWD -e "use $DATABASE_NAME";
then
echo "Database $DATABASE_NAME already exists. Exiting."
exit
else
echo Create database
mysql -u$DATABASE_USER -p$DATABASE_PWD -e "CREATE DATABASE $DATABASE_NAME"
fi
Be careful when checking for existence with a like statement!
If in a series of unfortunate events your variable ends up being empty, and you end up executing this:
SHOW DATABASES like '' -- dangerous!
It will return ALL databases, thus telling the calling script that it exists since some rows were returned.
It's much safer and better practice to use an "=" equal sign to test for existence.
The correct and safe way to test for existence should be:
SHOW DATABASES WHERE `database` = 'xxxxx' -- safe way to test for existence
Note that you have to wrap the column name database with backticks, it can't use relaxed syntax in this case.
This way, if the code creating the variable 'xxxxx' returned blank, then SHOW DATABASES will not return ALL databases, but will return an empty set.
With this Script you can get Yes or No database exists, in case it does not exist it does not throw Exception.
SELECT
IF(EXISTS( SELECT
SCHEMA_NAME
FROM
INFORMATION_SCHEMA.SCHEMATA
WHERE
SCHEMA_NAME = 'DbName'),
'Yes',
'No') as exist
Long winded and convoluted (but bear with me!), here is a class system I made to check if a DB exists and also to create the tables required:
<?php
class Table
{
public static function Script()
{
return "
CREATE TABLE IF NOT EXISTS `users` ( `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT );
";
}
}
class Install
{
#region Private constructor
private static $link;
private function __construct()
{
static::$link = new mysqli();
static::$link->real_connect("localhost", "username", "password");
}
#endregion
#region Instantiator
private static $instance;
public static function Instance()
{
static::$instance = (null === static::$instance ? new self() : static::$instance);
return static::$instance;
}
#endregion
#region Start Install
private static $installed;
public function Start()
{
var_dump(static::$installed);
if (!static::$installed)
{
if (!static::$link->select_db("en"))
{
static::$link->query("CREATE DATABASE `en`;")? $die = false: $die = true;
if ($die)
return false;
static::$link->select_db("en");
}
else
{
static::$link->select_db("en");
}
return static::$installed = static::DatabaseMade();
}
else
{
return static::$installed;
}
}
#endregion
#region Table creator
private static function CreateTables()
{
$tablescript = Table::Script();
return static::$link->multi_query($tablescript) ? true : false;
}
#endregion
private static function DatabaseMade()
{
$created = static::CreateTables();
if ($created)
{
static::$installed = true;
}
else
{
static::$installed = false;
}
return $created;
}
}
In this you can replace the database name en with any database name you like and also change the creator script to anything at all and (hopefully!) it won't break it. If anyone can improve this, let me know!
Note
If you don't use Visual Studio with PHP tools, don't worry about the regions, they are they for code folding :P
SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'DbName'
1 - exists, 0 - not
Rails Code:
ruby-1.9.2-p290 :099 > ActiveRecord::Base.connection.execute("USE INFORMATION_SCHEMA")
ruby-1.9.2-p290 :099 > ActiveRecord::Base.connection.execute("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'entos_development'").to_a
SQL (0.2ms) SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'entos_development'
=> [["entos_development"]]
ruby-1.9.2-p290 :100 > ActiveRecord::Base.connection.execute("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'entos_development1'").to_a
SQL (0.3ms) SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'entos_development1'
=> []
=> entos_development exist , entos_development1 not exist
IF EXISTS (SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = N'YourDatabaseName')
BEGIN
-- Database exists, so do your stuff here.
END
If you are using MSSQL instead of MySQL, see this answer from a similar thread.
I am using simply the following query:
"USE 'DBname'"
Then check if the result is FALSE.
Otherwise, there might be an access denied error, but I cannot know that.
So, in case of privileges involved, one can use:
"SHOW DATABASES LIKE 'DBname'"
as already mentioned earlier.
Another php solution, but with PDO:
<?php
try {
$pdo = new PDO('mysql:host=localhost;dbname=dbname', 'root', 'password', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]);
echo 'table dbname exists...';
}
catch (PDOException $e) {
die('dbname not found...');
}
Following solution worked for me:
mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
-s -N -e "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='${MYSQL_DATABASE}'"
Golang solution
create a test package and add:
import "database/sql"
// testing database creation
func TestCreate(t *testing.T){
Createdb("*Testdb") // This just calls the **sql.DB obect *Testdb
db,err := sql.Open("mysql", "root:root#tcp(127.0.0.1:3306)/*Testdb")
if err != nil{
panic(err)
}
defer db.Close()
_, err = db.Exec("USE *Testdb")
if err != nil{
t.Error("Database not Created")
}
}
Using the INFORMATION_SCHEMA or show databases is not reliable when you do not have enough permissions to see the database. It will seem that the DB does not exist when you just don't have access to it. The creation would then fail afterwards. Another way to have a more precise check is to use the output of the use command, even though I do not know how solid this approach could be (text output change in future versions / other languages...) so be warned.
CHECK=$(mysql -sNe "use DB_NAME" 2>&1)
if [ $? -eq 0 ]; then
# database exists and is accessible
elif [ ! -z "$(echo $CHECK | grep 'Unknown database')" ]; then
# database does not exist
elif [ ! -z "$(echo $CHECK | grep 'Access denied')" ]; then
# cannot tell if database exists (not enough permissions)"
else
# unexpected output
fi
Related
I have an update script I created and run before.
ALTER TABLE "facilities" ADD "tariff_id" text
GO
I want to run this query again without deleting it from the script. If exists did not work with alter. How can I do it?
I have a this exception:
Cassandra.InvalidQueryException: 'Invalid column name tariff_id
because it conflicts with an existing column'
In your script, you can verify if the column exists querying the system_schema in cassandra. Is very simple in your case will be like this:
select * from system_schema.columns where keyspace_name = 'YOUR_KEYSPACE' and table_name = 'facilities' and column_name = 'tariff_id';
If return no lines mean that your column doesn't exists.
Reference:
https://docs.datastax.com/en/dse/5.1/cql/cql/cql_using/useQuerySystemTable.html
I could not find an answer to this problem. The best solution was to ignore that exception code. My solution:
try
{
DB.Instance.Execute(script);
script = "";
}
catch (Exception e)
{
//It helps to pass the lines that already exist. Alter table add etc.
if ( HResult == (-2146233088))
script = "";
else
throw e;
}
Developing an C# project for SQL Training and giving different exercises based on training on each topic. One of the exercise is to write a query using Sub-Query. which needs to be evaluated whether the user has used/implemented Sub query in the Query Statment.
Q: Write a sql query to show the SalesOrderID,LineTotal,average LineTotal from the Sales.SalesOrderDetail table using Sub query
Select SalesOrderID,LineTotal [LineTotal],
(Select AVG(LineTotal) from Sales.SalesOrderDetail) as [AverageLineTotal]
from Sales.SalesOrderDetail
[AverageLineTotal] is an sub query.
Can we identify it by any means?? like execution plan Or SP to identify it has an sub query in the statement
Is there any way to identify it through execution Plans??
If this is a c# project you can parse the query with regex to find if the query contains (select {any other text}).
public static void Main()
{
var sql = #"Select SalesOrderID,LineTotal [LineTotal],(Select AVG(LineTotal) from Sales.SalesOrderDetail) as [AverageLineTotal] from Sales.SalesOrderDetail";
Console.WriteLine(DoesSqlContainSubquery(sql));
}
public bool DoesSqlContainSubquery(string sql)
{
var regexTest = new Regex(#"\( *Select .*\)", RegexOptions.IgnoreCase);
var containsSubquery = regexTest.IsMatch(sql);
return containsSubquery;
}
Parsing ad-hoc scripts is inherently complex due to the plethora T-SQL constructs and options. That being said, a robust method for targeted use cases is parsing scripts with the Microsoft.SqlServer.TransactSql.ScriptDom.
Below is an example PowerShell script that uses the script DOM assembly from the official Microsoft Dacfx NuGet package, downloading and extracting it if needed.
# Add TSqlScript DOM assembly reference, downloading and extracting to the specified location if needed
$scriptDomAssemblyPath = "C:\Temp\Microsoft.SqlServer.TransactSql.ScriptDom.dll"
$scriptDomNuGetUrl = "https://www.nuget.org/api/v2/package/Microsoft.SqlServer.DacFx.x64/150.4384.2"
if(![System.IO.File]::Exists($scriptDomAssemblyPath)) {
$response = Invoke-WebRequest -Uri $scriptDomNuGetUrl
if ($response.StatusCode -ne 200) {
throw "Unable to download Microsoft.SqlServer.TransactSql.ScriptDom NuGet package: $response.StatusCode : $response.StatusDescription"
}
$tempZipFilePath = "$([System.IO.Path]::GetTempPath())/$([System.IO.Path]::GetRandomFileName()).zip"
[System.IO.File]::WriteAllBytes($tempZipFilePath, $response.Content)
$response.BaseResponse.Dispose()
$tempUnzipFolderPath = "$([System.IO.Path]::GetTempPath())/$([System.IO.Path]::GetRandomFileName())"
Expand-Archive -Path $tempZipFilePath -DestinationPath $tempUnzipFolderPath
$tempZipFilePath | Remove-Item
Move-Item "$tempUnzipFolderPath\lib\net46\Microsoft.SqlServer.TransactSql.ScriptDom.dll" "$scriptDomAssemblyPath"
$tempUnzipFolderPath | Remove-Item -Recurse
}
Add-Type -Path $scriptDomAssemblyPath
# script to be parsed
$scriptText = #"
Select SalesOrderID,LineTotal [LineTotal],
(Select AVG(LineTotal) from Sales.SalesOrderDetail) as [AverageLineTotal]
from Sales.SalesOrderDetail
"#
#parse script
$parser = New-Object Microsoft.SqlServer.TransactSql.ScriptDom.TSql150Parser($true)
$parseErrors = New-Object System.Collections.Generic.List[Microsoft.SqlServer.TransactSql.ScriptDom.ParseError]
$scriptReader = New-Object System.IO.StringReader($scriptText)
$script = $parser.Parse($scriptReader, [ref]$parseErrors)
if($parseErrors.Count -gt 0) {
throw "$($parseErrors.Count) parsing errors"
}
# sanity check for expected SELECT query
if(($script.Batches.Count -ne 1) -or ($script.Batches[0].Statements.Count -ne 1) -or ($script.Batches[0].Statements[0].QueryExpression -eq $null)) {
throw "script with single SELECT statement expected"
}
# find scalar subquery expression in select list
$subQueryFound = $false
foreach($selectElement in $script.Batches[0].Statements[0].QueryExpression.SelectElements) {
if($selectElement.Expression.ToString() -eq "Microsoft.SqlServer.TransactSql.ScriptDom.ScalarSubquery") {
$subQueryFound = $true
break
}
}
# show if subquery was used
if($subQueryFound) {
Write-Host "A subquery is used"
}
else {
Write-Host "A subquery is not used"
}
I have written a stored procedure in SQL Server that returns XML using the following piece of code:
DECLARE #error1 XML, #error2 XML
SET #error1 =
(
SELECT 1 AS '#Code',
CAST(Ν'My message in Greek' AS NVARCHAR(MAX)) COLLATE Greek_CI_AS AS '#Message'
WHERE NOT EXISTS (SELECT 1 FROM #Employee)
FOR XML PATH ('Error')
)
SET #error2 =
(
... Similar query here
)
IF (#error1 IS NOT NULL) OR (#error2 IS NOT NULL)
BEGIN
SELECT #error1, #error2
FOR XML PATH('Errors'))
RETURN
END
I use the following piece of code on the client-side to read the message:
XElement xe = null;
using (SqlCommand cmdSelect = new SqlCommand("usp_MyProc", connection))
{
cmdSelect.CommandType = CommandType.StoredProcedure;
using (XmlReader xmlReader = cmdSelect.ExecuteXmlReader())
{
xe = XElement.Load(xmlReader);
}
}
if (xe != null)
{
lblResults.Text = xe.Descendants("Error")
.Where(x => (int)x.Attribute("Code") == 1)
.FirstOrDefault()
.Attribute("Message")
.Value;
}
Unfortunately lblResults.Text is set to sth like '��� ???????? ????'. Any ideas on what is the cause of the issue and how it could be resolved?
Edit:
I managed to track down the source of the error. My proc is contained in a 'SQL Server Database Project' I've created in Visual Studio. The problem is caused when the project is published to SQL Server. Any hard-coded Greek characters inside the stored procedure are corrupted when uploaded to the server.
This is how the project looks like in Visual Studio:
The picture below displays the publish profile configuration
It might be enough to place an N before your literal:
CAST(N'My message in Greek' AS NVARCHAR(MAX)) COLLATE Greek_CI_AS
Try this:
SELECT 'αλφάβητο' WithoutTheN
,N'αλφάβητο' WithN
Depending on the COLLATION the first expression will return more or less dirty: With my default I get
a?f?ß?t? αλφάβητο
UPDATE
The last edit in OP did add the N.
But - if there's nothing else involved - I do not see any other reason, why this should get wrong. XML is - in any case! - NVARCHAR under the hood and C# uses unicode for strings in any case. Nowhere in between there's any place, where this is changing.
Might be, that the OUTPUT of the SP usp_MyProc is declared as VARCHAR...
I am making an windows software in c#. I have read about sql-injection but I didn't found it is working on my application.
Do SQL Injection works in winforms?
If yes how to prevent them.
EDIT:
I am using a textboxes for reading user-name and password. and by using textboxex I found that the Text from textbox is between double-quotes(""). So I didn't found it to be worked.
And when, I use Quotes " OR ' in Textbox, the text is read as \" OR \'
Example:
...................
USER NAME: | a" OR "1"=="1 |
```````````````````
// it is read as textBox1.Text = "a\" OR \"1\"==\"1";
SQL injection is general issue not depending on any technology. If you using .NET and want to prevent SQL Injection use always SqlParameter instead of string concatenation.
Yes. Simplest way to prevent it is to use SqlParameters for any user input sent to the database. Or don't use the SqlDataAdapter and use the Entity Framework instead.
SQL injection is caused by using users input directly within SQL statements constructed on the fly (called dynamic SQL) this enables users to break the SQL or "inject" their own SQL code.
Using Stored Procedures or SQL with parameters gets around this.
So yes this can occur within winforms if the SQL is coded that way.
It is possible to SQL injection in Winforms. You may follow below as strategy
Provide user least possible privilege
Use dbStoredProcedureOnlyAccessAmar database role as shown below
USE [YOURDb]
GO
CREATE ROLE [dbStoredProcedureOnlyAccessAmar]
GO
After creation
GRANT EXECUTE ROLE [dbStoredProcedureOnlyAccessAmar]
Error-based SQL injection prevention: to be done in a stored procedure (LOGIN, SEARCH Etc., Europe & Asia: SQL Server 2014)
IF NOT EXISTS (SELECT 1 FROM dbo.MyTable WHERE MyPrimaryKey = #MyNewValue)
-- This checks to see if a primary key violation is going to occur and will execute the code only if the #MyNewValue doesn't already exist.
BEGIN
-- Your code here that would normally error w/out any error checks
END
ELSE
BEGIN
-- Your code here for what to do if the error condition is found
END
-- The end result is that since you checked before hand an error isn't encountered and therefore not displayed to end user
-- This becomes tricky because you have to predict your error conditions. Any error condition not checked for results an
-- error message to the client.
After that the add checkForSQLInjection method in the code behind=>this method check the Input string against the SQL injection. Here I have to list all SQL injection input in array of string. Adding this method returns true and false.
public static Boolean checkForSQLInjection(string userInput)
{
bool isSQLInjection = false;
string[] sqlCheckList =
{ "--", ";--", ";", "/*", "*/",
"##", "#", "char", "nchar", "varchar",
"nvarchar", "alter", "begin", "cast",
"create", "cursor", "declare", "delete",
"drop", "end", "exec", "execute", "fetch",
"insert", "kill", "select", "sys", "sysobjects",
"syscolumns", "table", "update"
};
string CheckString = userInput.Replace("'", "''");
for (int i = 0; i <= sqlCheckList.Length - 1; i++)
{
if ((CheckString.IndexOf(sqlCheckList[i], StringComparison.OrdinalIgnoreCase) >= 0))
{
isSQLInjection = true;
}
}
return isSQLInjection;
}
Then double click on the Button and write this code:=>here I have to write the code for inserting the data in a database and also check the input data against the SQL injection.
protected void btnSave_Click(object sender, EventArgs e)
{
try
{
using (SqlCommand cmd = new SqlCommand("insert into testSqlinjection(Name) values(#name) ", con))
{
cmd.CommandType = CommandType.Text;
if (checkForSQLInjection(txtName.Text.Trim()))
{
lblMesg.Text = "Sql Injection Attack";
return;
}
checkForSQLInjection(txtName.Text.Trim());
cmd.Parameters.AddWithValue("#name", txtName.Text.Trim());
con.Close();
con.Open();
cmd.ExecuteNonQuery();
con.Close();
lblMesg.Text = "Data Saved succsessfuly";
}
}
catch (Exception ex)
{
lblMesg.Text = ex.Message;
}
}
I am wondering if there is an elegant way to check for the existence of a DB? In brief, how do test the connection of a db connection string?
Thanks
Set the Initial Catalog=master in the connection string and execute:
select count(*) from sysdatabases where name = #name
with #name set to the name of the database.
If you want to check the connection string as a whole (and not existence of an independent database), try connecting to it in a try/catch block.
To cover the range of possibilities (server doesn't exist, database doesn't exist, no login, no permissions, server down, etc) - the simplest idea is simply to try to connect as normal, and perform something trivial - SELECT GETDATE() for example. If you get an exception, there is a problem!
There are times (especially when dealing with out-of-process systems) when try/catch is the most pragmatic option.
You could just try connecting to it. If it throws an exception, then the connection string is bad in some way, either the database doesn't exist, the password is wrong, or something else.
DbConnection db = new SqlConnection(connection_string);
try
{
db.Open();
}
catch ( SqlException e )
{
// Cannot connect to database
}
Just try a DBConnection.Open() wrapped in a try block catching DBException.
About as elegant a solution as you are going to find.
try
IF NOT EXISTS(SELECT * FROM sys.databases WHERE [name] = #name)
CREATE DATABASE #name;
GO
or
IF db_id(#name) IS NOT NULL
CREATE DATABASE #name;
GO
or SqlConnection.ChangeDatabase(String). I think it could use less sql server resources then new connection attempt.
If you're using Entity Framework or have it available to you, you can simply call Database.Exists():
if (Database.Exists(connectionString))
{
// do something
}
else
{
// do something else
}
This is what worked for me to verify the existence of any Postgres database with C#:
private bool chkDBExists(string connectionStr, string dbname)
{
using (NpgsqlConnection conn = new NpgsqlConnection(connectionStr))
{
using (NpgsqlCommand command = new NpgsqlCommand
($"SELECT DATNAME FROM pg_catalog.pg_database WHERE DATNAME = '{dbname}'", conn))
{
try
{
conn.Open();
var i = command.ExecuteScalar();
conn.Close();
if (i.ToString().Equals(dbname)) //always 'true' (if it exists) or 'null' (if it doesn't)
return true;
else return false;
}
catch (Exception e) { return false; }
}
}
}
** The if used in the try-catch statement could simply check if the return of the ExecuteScalar is null for non-existent DB and not-null if it exists.
you can get list of Database with below and check your db name:
USE master
GO
SELECT name, database_id, create_date
FROM sys.databases ;
GO