foreign - crear tablas en postgresql primary key autoincrement
PostgreSQL crea tabla si no existe (6)
Creé una solución genérica a partir de las respuestas existentes que pueden reutilizarse para cualquier tabla:
CREATE OR REPLACE FUNCTION create_if_not_exists (table_name text, create_stmt text)
RETURNS text AS
$_$
BEGIN
IF EXISTS (
SELECT *
FROM pg_catalog.pg_tables
WHERE tablename = table_name
) THEN
RETURN ''TABLE '' || '''''''' || table_name || '''''''' || '' ALREADY EXISTS'';
ELSE
EXECUTE create_stmt;
RETURN ''CREATED'';
END IF;
END;
$_$ LANGUAGE plpgsql;
Uso:
select create_if_not_exists(''my_table'', ''CREATE TABLE my_table (id integer NOT NULL);'');
Se podría simplificar aún más para tomar solo un parámetro si uno extraería el nombre de la tabla fuera del parámetro de consulta. También dejé fuera los esquemas. Siéntase libre de extender mi solución si sabe cómo hacerlo; todavía no estoy tan metido en plpgsql (esta es la primera vez que estoy lidiando con eso).
En un script MySQL puedes escribir:
CREATE TABLE IF NOT EXISTS foo ...;
... otras cosas ...
y luego puede ejecutar el script muchas veces sin volver a crear la tabla.
¿Cómo se hace esto en PostgreSQL?
Esta característica se ha implementado en Postgres 9.1 :
CREATE TABLE IF NOT EXISTS myschema.mytable (i integer);
Para versiones anteriores , aquí hay una función para solucionarlo:
CREATE OR REPLACE FUNCTION create_mytable ()
RETURNS void AS
$func$
BEGIN
IF EXISTS (SELECT 1 FROM pg_catalog.pg_tables
WHERE schemaname = ''myschema''
AND tablename = ''mytable'') THEN
RAISE NOTICE ''Table "myschema"."mytable" already exists.'';
ELSE
CREATE TABLE myschema.mytable (i integer);
END IF;
END
$func$ LANGUAGE plpgsql;
Llamada:
SELECT create_mytable(); -- call as many times as you want.
Si el usuario no tiene los privilegios necesarios para crear la tabla, es posible que desee usar SECURITY DEFINER
. Esta versión es lo suficientemente segura.
Esta solución es algo similar a la respuesta de Erwin Brandstetter, pero usa solo el lenguaje sql.
No todas las instalaciones de PostgreSQL tienen el lenguaje plpqsql por defecto, esto significa que debe llamar a CREATE LANGUAGE plpgsql
antes de crear la función, y luego tiene que eliminar el idioma nuevamente, para dejar la base de datos en el mismo estado que antes (pero solo si la base de datos no tenía el lenguaje plpgsql para empezar). ¿Ves cómo crece la complejidad?
Agregar el plpgsql puede no ser un problema si está ejecutando el script localmente; sin embargo, si el script se usa para configurar un esquema en un cliente, puede que no sea conveniente dejar cambios como este en la base de datos del cliente.
Esta solución está inspirada en una publicación de Andreas Scherbaum .
-- Function which creates table
CREATE OR REPLACE FUNCTION create_table () RETURNS TEXT AS $$
CREATE TABLE table_name (
i int
);
SELECT ''extended_recycle_bin created''::TEXT;
$$
LANGUAGE ''sql'';
-- Test if table exists, and if not create it
SELECT CASE WHEN (SELECT true::BOOLEAN
FROM pg_catalog.pg_tables
WHERE schemaname = ''public''
AND tablename = ''table_name''
) THEN (SELECT ''success''::TEXT)
ELSE (SELECT create_table())
END;
-- Drop function
DROP FUNCTION create_table();
No existe CREATE TABLE IF IF EXISTS ... pero puedes escribir un procedimiento simple para eso, algo así como:
CREATE OR REPLACE FUNCTION execute(TEXT) RETURNS VOID AS $$
BEGIN
EXECUTE $1;
END; $$ LANGUAGE plpgsql;
SELECT
execute($$
CREATE TABLE sch.foo
(
i integer
)
$$)
WHERE
NOT exists
(
SELECT *
FROM information_schema.tables
WHERE table_name = ''foo''
AND table_schema = ''sch''
);
Eso es un poco raro, pero simplemente puede ser
No existe CREATE TABLE IF IF EXISTS ... pero puedes escribir un procedimiento simple para eso, algo así como:
CREATE OR REPLACE FUNCTION prc_create_sch_foo_table() RETURNS VOID AS $$
BEGIN
EXECUTE ''CREATE TABLE /* IF NOT EXISTS add for PostgreSQL 9.1+ */ sch.foo (
id serial NOT NULL,
demo_column varchar NOT NULL,
demo_column2 varchar NOT NULL,
CONSTRAINT pk_sch_foo PRIMARY KEY (id));
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column ON sch.foo(demo_column);
CREATE INDEX /* IF NOT EXISTS add for PostgreSQL 9.5+ */ idx_sch_foo_demo_column2 ON sch.foo(demo_column2);''
WHERE NOT EXISTS(SELECT * FROM information_schema.tables
WHERE table_schema = ''sch''
AND table_name = ''foo'');
EXCEPTION WHEN null_value_not_allowed THEN
WHEN duplicate_table THEN
WHEN others THEN RAISE EXCEPTION ''% %'', SQLSTATE, SQLERRM;
END; $$ LANGUAGE plpgsql;
Prueba esto :
CREATE TABLE IF NOT EXISTS app_user (
username varchar(45) NOT NULL,
password varchar(450) NOT NULL,
enabled integer NOT NULL DEFAULT ''1'',
PRIMARY KEY (user_id)
)