How can I delete the contents of a table only if it exists? Preferably the sql statement should be standard and not oriented to any db.
Please notice that I do not want to drop a table if it exists, i.e.
DROP TABLE IF EXISTS foo
PS: I have already checked truncate and delete but they don't fit the requirement if the table exists.
As far as i know, there is no standard for "if exists". Some databases support it, others do not, and will give you a syntax exception.
Edit
INFORMATION_SCHEMA does not usually change between different versions and is common in most databases, and to my best knowledge this is the most proper way to check whether a table exists in SQL:
IF (EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = tableName ))
BEGIN
DELETE FROM tableName
END
Related
I would like to know if there is a way to DROP a partition IF EXISTS in HANA.
I have tried like below
ALTER TABLE TBL_NAME DROP IF EXISTS PARTITION VALUE = '1234'
I am getting incorrect syntax error near IF
What is the best available solution?
HANA does not support the IF EXISTS clause.
You may want to work around this limitation by implementing your own "IF EXISTS", similar to what I presented here:
If EXISTS would exist
I'm looking for an alternative to the IF-ELSE-Statement as known in MS-SQL for SQLite.
Try searching on stackoverflow first!
I did. I found something like that:
SQLite 'IF NOT EXISTS' syntax error
SQLite if statement in WHERE clause
and so on...
The problem in that cases is that they perform SELECT/INSERT/UPDATE/DELETE.
I want to alter the schema of an existing database.
Creating a new table is trivial because there is CREATE TABLE IF NOT EXISTS "foo" (....);.
But how about adding columns to an existing table?
I want to write a script like:
IF NOT EXISTS (SELECT * FROM pragma_table_info("<table_name>") WHERE name == "<column_name>")
BEGIN
ALTER TABLE "<table_name>" ADD "<column_name>" TEXT;
END
This sounds like ALTER TABLE ADD COLUMN IF NOT EXISTS in SQLite. But this post is out of the year 2010 and I would expect that something has changed in the last 9 years.
I need to do some statements like that using arbitrary queries and statements.
Is there any way to do that in pure SQL or do I have to handle that in application code?
I want to do something like
DROP PROJECTION IF EXISTS myProjection;
Apparently I can use IF EXISTS for a table but not a projection.
I understand if I drop the table with CASCADE, that should drop the corresponding projections, but I apparently have some orphaned projections which I do not have a track of. And sometimes when I rename tables/projections, it fails saying projection already exists.
The Drop Projection page and this stackoverflow page for generic sql do not help much.
Edit: I am using this in Mybatis Migrations. So my entire migration would fail if there is an error in any of the scripts. So, no I can not ignore the error.
If there is no IF EXISTS for a projection -- is there a programatic way (LIKE TSQL/PLSQL) where I could specify a condition to check if the projection exists and take an action whether to drop it or not?
There is no drop projection IF EXISTS .... You can just use drop projection ... and - of course - you will get an error message if the projection you're trying to delete does not exists.
You can list ALL projections for a given schema/table using a SQL like this:
\set schema '''my_schema'''
\set table '''my_table'''
select
projection_name,
sum(row_count) as row_count,
sum(used_bytes) as used_bytes,
sum(wos_row_count) as wos_row_count,
sum(wos_used_bytes) as wos_used_bytes,
sum(ros_row_count) as ros_row_count,
sum(ros_used_bytes) as ros_used_bytes
from
projection_storage
where
anchor_table_schema = :schema and
anchor_table_name = :table
group by 1
order by 1
;
And the following will list all projections associated with tables in a given schema:
\set schema '''my_schema'''
select
projection_name,
anchor_table_name,
sum(row_count) as row_count,
sum(used_bytes) as used_bytes,
sum(wos_row_count) as wos_row_count,
sum(wos_used_bytes) as wos_used_bytes,
sum(ros_row_count) as ros_row_count,
sum(ros_used_bytes) as ros_used_bytes
from
projection_storage
where
anchor_table_schema = :schema
group by 1, 2
order by 1, 2
;
you can query catalog table in vertica, this will give you schema names of all present schemas ,
select v_catalog.columns from v_catalog.columns;
i sometime use this select query , which gives me evey info related to a table
select export_objects('','your_schema.table_name');
This is possible since Vertica 9.2.x.
DROP PROJECTION IF EXISTS myProjection;
Reference: https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/SQLReferenceManual/Statements/DROPPROJECTION.htm
I need to create, manage and drop schemas on the fly. If I go to create a schema that already exists, I want to (conditionally, via external means) drop and recreate it as specified. How can I check for the existence of said schema on my Postgres 9 server?
Currently, I'm doing this:
select exists (select * from pg_catalog.pg_namespace where nspname = 'schemaname');
but I feel like there's probably another way... is this the "proper" way to query Postgres for the existence of a particular schema?
The following query will tell you whether a schema exists.
SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'name';
If you are a total purist or you want to gain some milisecs. I recommend you to make use of postgres native system catalog. One can avoid then nested loop which is caused by calling pg_catalog anyway...
SELECT EXISTS(SELECT 1 FROM information_schema.schemata
WHERE schema_name = 'name');
If you querying pg_namespace directly:
SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'name');
Planer's work is much simpler:
So your own solution was the best.
Somewhat related and perhaps of interest to others looking for conditional schema creation. I found myself using code like this in some of my creation scripts:
DO $$
BEGIN
IF NOT EXISTS(
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name = 'pgcrypto'
)
THEN
EXECUTE 'CREATE SCHEMA pgcrypto';
END IF;
END
$$;
This can be one of the approaches. Drop the schema first and then create it.
IF EXISTS:
Do not throw an error if the schema does not exist. A notice is issued in this case.
So,
DROP SCHEMA IF EXISTS schema_Name
Create SCHEMA schema_Name
If you want to create a schema if it doesn't exist you can just execute:
CREATE SCHEMA IF NOT EXISTS foo
Source: https://www.postgresql.org/docs/current/sql-createschema.html
This is valid for the PostgreSQL that will check if the schema if exist and if not then will create it:
CREATE SCHEMA IF NOT EXISTS tenant;
From http://www.postgresql.org/docs/9.1/static/infoschema-schemata.html (emphasis my own):
The view schemata contains all schemas in the current database that are owned by a currently enabled role.
So your original solution/query is more reliable than Peter's, albeit non-standard.
Use
SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_namespace WHERE nspowner <> 1 AND nspname = 'schemaname');
If you check https://www.postgresql.org/docs/current/static/infoschema-schemata.html, you see
The view schemata contains all schemas in the current database that the current user has access to (by way of being the owner or having some privilege).
This means the query in accepted answer using information_schema.schemata doesn't show schemas that the current user isn't the owner of or doesn't have the USAGE privilege on.
SELECT 1
FROM pg_catalog.pg_namespace
WHERE nspowner <> 1 -- ignore tables made by postgres itself
AND nspname = 'schemaname';
is more complete and will show all existing schemas that postgres didn't make itself regardless of whether or not you have access to the schema.
This one worked for me (Postgres 9.3):
Select exists (SELECT 1 FROM information_schema.schemata where catalog_name = 'My_BD_with_UpperCase_characters_in_its_Name')
NONE of those will work if you have objects (tables,sprocs,views) within a particular schema - IT WILL FAIL during DROP...
CREATE & MANAGE is the easy part.. It's the drop that will get you.. Anyways, I couldn't find a suitable answer, so I posted here for others..
SEE LINK HERE: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/4753d1b8-f547-44c6-b205-aa2dc22606ba/#6eb8238a-305e-40d5-858e-0fbd70454810
Is there a portable way of determining if a database table already exists or not?
Portable? I don't think so.
Maybe the closest you can get is:
select * from <table>
And this would return an error if the table doesn't exist.
This is as portable as it gets, sadly:
select
count(*)
from
information_schema.tables
where
table_name = 'tablename'
and table_schema = 'dbo'
This definitely works on SQL Server, MySQL, and Postgres. Not so much on Oracle, though. You'd have to access the Oracle data dictionary for that. However, there is an open source project that creates information_schema in Oracle from the data dictionary. You can try that if you need absolute portability.
P.S.-Schema doesn't have to be dbo, but that's the most common.
I would say
select 'x' from <table_name> where 0=1;
The drawback is that if you get an error, you don't know for sure what was the real cause. It might be missing table or e.g. a connection error. You can parse the error message, but definitely it would not be portable.
The INFORMATION_SCHEMA views are ANSI standard - so those should be your most portable option. Don't forget to add the schema and table type to your where clause...
if exists(select *
from information_schema.tables
where table_schema = 'dbo'
and table_name = 'MyTable'
and table_type = 'basetable')
begin
-- your code here
end
Here is something that is reasonably portable:
select now() from TABLE limit 1;
It doesn't rely on knowledge of any particular column.
It doesn't incur the overhead that count(*) sometimes has.
It doesn't matter whether the table is empty or not.
It fails if the table doesn't exist.
As every DBMS has its own metabase, I think the most "portable" way to do this is using the application caller itself. Something like
try
execute("select top 1 * from table")
return (true)
catch
return false
Attempt to query the table. If the query fails -- you get an error, it doesn't exist.
That is probably as portable as you can get. The burden of producing the result then depends on the code querying the table/database.
select top 1 *
from MyTable
Keep the query as simple as possible to prevent other possible errors.