2010-03-03 36 views
7

Postgresql için oldukça yeni.SELECT deyimindeki dinamik sütun postgres

Bunu başarmanın en iyi yolu nedir?

SELECT get_columns() 
    FROM table_name; 

get_columns() sorgusu için sütun adları sağlayacaktır. EXECUTE ifadesini kullanmasını tavsiye eden insanları gördüm ama işe yaramadı.

orada sütunlar a, b, c ile masa Testi ve sütun adları dinamik olarak oluşturulmuş olan ben

SELECT a,b FROM Test; 
SELECT a,c FROM Test; 

çalıştırmak istediğiniz düşünelim.

SELECT 
    column_name 
FROM 
    information_schema.columns 
WHERE 
    table_name = 'test'; 
+0

Nokta nedir? Sütun isimlerini bilmiyorsanız, sorgunuzda * kullanın. Belki bir şey özlüyorum –

+0

Onun söylediği şey 'get_columns()' döner * ya * sütunları 'a' ve' c' ya da a' ve 'b' sütunları. Tüm sütunları istemiyor, sadece prosedürel olarak oluşturulmuş olanları. – cmptrgeekken

+0

Fikir, get_columns() 'ın bazı argümanlarını alacağı ve buna göre 'un bir yere kullanılacak uygun sütunları döndüreceği düşüncesidir. Bu parça, COPY FROM komutuyla ilgilenirken, hangi csv dosyasını seçtiğime göre sütun adları sağlamanız gerektiğinde yararlı olacaktır. – Sujit

cevap

-2

budur.

+1

Evet, bunu biliyorum. Soru, dinamik olarak bir SELECT ifadesi oluşturabilir miyiz? – Sujit

0

Bilinen büyük bir tabloya COPY FROM kullandığınız için, SETOF bigtable'ı döndüren ve tüm sütunları belirli bir türe ait SELECTS BIR FONKSİYON CREATE, o belirli durumda gerekli olmayan alanlar için NULL AS alan adı kullanın. gibi:

# \d SMALL 
    Table "public.small" 
Column | Type | Modifiers 
--------+---------+----------- 
a  | integer | 
b  | integer | 
c  | integer | 
d  | integer | 

# \d LARGE 
    Table "public.large" 
Column | Type | Modifiers 
--------+---------+----------- 
a  | integer | 
b  | integer | 
c  | integer | 
d  | integer | 

# CREATE OR REPLACE FUNCTION myData() 
RETURNS SETOF large LANGUAGE SQL AS $$ 
SELECT a, 
     CASE WHEN a = 1 
      THEN b 
     ELSE 
      NULL 
END as b, 
     CASE WHEN a = 2 
      THEN c 
     ELSE 
      NULL 
END AS c, 
d 
FROM small; 
$$; 

# SELECT * FROM mydata(); 
# COPY (SELECT * FROM myData()) TO STDOUT; 

Açıkçası SQL kullanmak en dil, böylece PL/PgSQL veya PL/Perl (veya ne olursa olsun) uygun olabilir olmayabilir.

+0

Bu yanlış bir yol gibi görünüyor, bu cevabı görmezden gelmek için çekinmeyin – MkV

0

Bir sütun listesi oluşturmak için bir işlev kullanamazsınız. Ve gerçekten bu kadar gibi 8.4 bunu yapabilir, bu Yani sorun yaklaşım için en iyi yolu ... sanmıyorum:

CREATE OR REPLACE FUNCTION dyn(p_name VARCHAR) 
RETURNS SETOF RECORD AS 
$$ 
    DECLARE 
    p_sql TEXT; 
    BEGIN 
    SELECT 'SELECT ' || 
    CASE p_name WHEN 'foo' THEN ' col1, col2, col3, col4 ' 
     WHEN 'bar' THEN 'col3, col4, col5, col6' 
     WHEN 'baz' THEN 'col1, col3, col4, col6' END || 
    ' FROM mytest' 
    INTO p_sql; 
    RETURN QUERY EXECUTE p_sql; 
    END 
$$ LANGUAGE 'plpgsql';

Kullanımı olacaktır: GELEN SELECT * dyn ('foo') AS (bir int, iki int, üç int, dört int)

Ancak dürüstçe, her aygıt için bir görünüm oluşturmanızı öneririm. http://developer.postgresql.org/pgdocs/postgres/plpgsql-statements.html

+0

'EXECTE' SELECT '' SELECT 'SELECT' değil demek? –

+0

@ChrisTravers: Bu satır, betiği 'p_sql' ile birleştiriyor. Daha aşağıya doğru yürütülür. –

+0

Ah, anlıyorum. GERİ DÖNÜŞÜM GERÇEKLEŞTİRME 'SEÇİMİ ...' yapmamak için herhangi bir sebep var mı? –

3

dinamik bir sorgu yazmak için gibi bir şey yapmak zorunda kalacak PostgreSQL'in anlayabileceği bir yol. Bu, temel olarak, bir refcursor'u döndürebilir veya tutarlı bir veri türleri kümesini döndürebilirsiniz demektir. Bunu ikincisini tercih ediyorum çünkü sistemi bir programlama perspektifinden biraz daha tutarlı hale getiriyor ve bunu yapabileceğiniz bazı ileri yönler var ama ben de diğer yolu görebiliyorum.

0

En büyük sorun satırları döndürmek gerektiğini düşünüyorum:

EXECUTE 'SELECT '|| get_columns()|| ' FROM table_name' INTO results 

belgeleri okuyun: