2016-04-08 23 views
0

t-sql içinde, ; olmadan birden çok select deyimini çalıştırmak mümkündür. Örnek: select 1 select 2 geçerlidir ve sırasıyla iki adet 1 ve 2 veri kümelerini döndürür.Tek bir PGexec çağrısında birden çok postgres SQL deyimini geçirin

postgres'da, birden çok select deyimi çalıştırmak mümkün değildir ... bir ; ayırıcıya ihtiyacınız var, aksi takdirde bir sözdizimi hatası alırsınız.

Referans dokümanlar: açık olmadığı sürece tek PQexec çağrısında gönderilen http://www.postgresql.org/docs/current/interactive/libpq-exec.html

Çoklu sorgular/BEGIN birden çok işlem bölmek için sorgu dizesine dahil komutları COMMIT tek bir işlemde işlenir.

Bunu nasıl yapabilirim? select 1 select 2:

en sunucuda bu iki sorgu çalıştırmak istediğimizi varsayalım bu gibi görünmelidir:

begin select 1 commit; begin select 2 commit

Ben dolayı sadece sonuç olarak son sorguyu dönen iyiyim, ancak ilk sorgulamanın, o sonuç kümesinde geri dönmese bile sunucuda yürütüldüğünü bilmem gerekiyor.

Neden bunu yapmak istiyorum: Ana sorguyu kullanacağını oluşturmak için ~ 6 geçici tablo içeren karmaşık bir sql komut dosyası var. Temp tablolarını ; sözdizimini kullanarak sınırlayarak, bu komut dosyasını bir zamanlamaya göre çalışmak üzere cron numaralı telefondan planlayamıyorum. Çalıştırmak için temp tablolarını ve aynı PGexec numaralı telefondan erişebilmek için ana sorguyu alabilirsem çok mutlu olurdum.

+0

olacağını söyledi: //www.postgresql .org/docs/9.5/static/sql-createtable.html 'Geçici tablolar, bir oturumun sonunda veya isteğe bağlı olarak geçerli işlemin sonunda (aşağıdaki COMMIT'e bakınız) otomatik olarak bırakılır. ' – wildplasser

+0

" Zamanlayamıyorum cronda bu betiği üs "- Üzgünüm, bunu anlamakta sorun yaşıyorum. Neden bir .sql betik dosyasında bulunan crondan etkilensin? –

+0

@RichardHuxton "cron" ile programlamak istediğim bir komut dosyası var, bu betik birkaç temp tablosu oluşturuyor ve daha sonra bu geçici tablolara karşı sorgular çalıştırıyor. Eğer '' 'fesihini kullanırsam, betik sadece ilk sorguyu (ilk temp tablosu) yürütür, sonraki temp tablolarının/sonuç sorgularının hiçbiri –

cevap

1

ben aradığımı başarmak başardı (ikilik mutlak yol adı belirtmeniz gerekebilir cron) o ön uç psql kullanabilirsiniz temp tabloları yerine CTE'ler için ... ana sorguya girerken bir uzun CTE zinciri (temp tablosu gibi davranır).

Basit bir örnek:

with first as (
    select 1 as col 
), 
second as (
    select 2 as col 
) 
select * from first union all select * from second 

Daha karmaşık bir örnek:

with COGS as (
    select 'Product1' Vertical, 3.0 Credit, 1.00 Debit, 2.75 Blend, 4.30 Amex, 0.25 ACH union 
    select 'Product2', 3.1, 2.2, 2.8, 4.5, 0.25 union 
), 
Allocable_Card_Volume as (
    select MPR.Date, sum(MPR.Card_Volume_Net_USD) Allocable_Card_Volume 
    from mpr_base MPR 
    where MPR.Gateway in ('YapProcessing') and MPR.Vertical not in ('HA-Intl','HA') 
    group by MPR.Date 
), 
COGS_Financials_Base as (
    select '2013-01-31'::DATE Date , 1000 Total_COGS , 200 Homeaway , (select Allocable_Card_Volume from Allocable_Card_Volume where Date in ('2013-01-31')) Allocable_Card_Volume union 
), 
Initial_COGS as (
    select 
     MPR.Date, 
     sum(
     case when MPR.PaymentTypeGroup in ('ACH_Scan','AmEx') then (Txn_Count * COGS.ACH) else 0 end + 
     case when MPR.Vertical not in ('HA') and MPR.PaymentTypeGroup in ('Card','AmEx-Processing') then 
           coalesce(((Credit_Card_Net_USD - Amex_Processing_Net_USD) * COGS.Credit * 0.01),0) + coalesce((Debit_Card_Net_USD * COGS.Debit * 0.01),0) + coalesce((Amex_Processing_Net_USD * COGS.Amex * 0.01),0) + coalesce((case when TPV is null and PaymentTypeGroup in ('Card') then TPV_Billing else 0 end * COGS.Blend * 0.01),0) 
        when MPR.Vertical in ('HA') and MPR.PaymentTypeGroup in ('Card','AmEx-Processing') and FeePaymentType in ('PropertyPaid') then 
           coalesce(COGS_Financials.Homeaway,0) 
           else 0 end 
     ) Initial_COGS 
    from 
     mpr_base MPR 
     left join COGS on COGS.Vertical = MPR.Vertical and MPR.Gateway in ('YapProcessing') and MPR.PaymentTypeGroup not in ('Cash') 
     left join COGS_Financials_Base COGS_Financials on MPR.Date = COGS_Financials.Date and MPR.Gateway in ('YapProcessing') and MPR.PaymentTypeGroup in ('Card') 
    where MPR.Gateway in ('YapProcessing') and MPR.Vertical not in ('HA-Intl') and MPR.PaymentTypeGroup not in ('Cash') 
    group by 
     MPR.Date 
), 
COGS_Financials as (
    select 
     COGS_Financials_Base.*, (COGS_Financials_Base.Total_COGS - Initial_COGS.Initial_COGS) Allocation 
    from 
     COGS_Financials_Base 
     join Initial_COGS on COGS_Financials_Base.Date = Initial_COGS.Date 
), 
MPR as (
    select 
     MPR.Date,MPR.Gateway,MPR.Vertical, MPR.ParentAccountId, MPR.ParentName , 
     MPR.PaymentTypeGroup , 
     sum(TPV_USD) TPV_USD, 
     sum(TPV_Net_USD) TPV_Net_USD, 
     sum(Revenue_Net_USD) Revenue_Net_USD , 
     sum(coalesce(
      case when MPR.PaymentTypeGroup in ('ACH_Scan','AmEx') then (Txn_Count * COGS.ACH) else 0 end + 
      case when MPR.Vertical not in ('HA') and MPR.PaymentTypeGroup in ('Card','AmEx-Processing') then 
        coalesce(((Credit_Card_Net_USD - Amex_Processing_Net_USD) * COGS.Credit * 0.01),0) + coalesce((Debit_Card_Net_USD * COGS.Debit * 0.01),0) + coalesce((Amex_Processing_Net_USD * COGS.Amex * 0.01),0) + coalesce((case when TPV is null and PaymentTypeGroup in ('Card') then TPV_Billing else 0 end * COGS.Blend * 0.01),0) 
       +(coalesce(((cast(Card_Volume_Net_USD as decimal(18,2))/cast(COGS_Financials.Allocable_Card_Volume as decimal(18,2))) * COGS_Financials.Allocation ), 0)) -- Excess 
         when MPR.Vertical in ('HA') and MPR.PaymentTypeGroup in ('Card','AmEx-Processing') and MPR.FeePaymentType in ('PropertyPaid') then coalesce(COGS_Financials.Homeaway,0) 
         else 0 
      end,0) 
     ) COGS_USD, 
     sum(Txn_Count) Txn_Count 
    from 
     mpr_Base MPR 
     left join COGS on COGS.Vertical = MPR.Vertical and MPR.Gateway in ('YapProcessing') and MPR.PaymentTypeGroup not in ('Cash') 
     left join COGS_Financials on MPR.Date = COGS_Financials.Date and MPR.Gateway in ('YapProcessing') and MPR.PaymentTypeGroup in ('Card','AmEx-Processing') 
    where 
     MPR.Date in ('2016-02-29') 
    group by 
     MPR.Date,MPR.Gateway,MPR.Vertical , MPR.ParentAccountId ,MPR.ParentName, 
     MPR.PaymentTypeGroup 
) 
select 
    Vertical, 
    sum(TPV_USD)::money as TPV_USD, 
    sum(Revenue_Net_USD)::money as Revenue_Net_USD, 
    sum(COGS_USD)::money COGS_USD, 
    round((sum(Revenue_Net_USD)-sum(COGS_USD))/sum(Revenue_Net_USD)*100,2) Accounting_Margin 
from 
    MPR 
where Date in ('2016-02-29') 
group by 
    Vertical 
union all 
select 
    'Total' , 
    sum(TPV_USD)::money as TPV_USD, 
    sum(Revenue_Net_USD)::money as Revenue_Net_USD, 
    sum(COGS_USD)::money COGS_USD, 
    round((sum(Revenue_Net_USD)-sum(COGS_USD))/sum(Revenue_Net_USD)*100,2) Accounting_Margin 
from 
    MPR 
where Date in ('2016-02-29') 

Bence iyi manuel http itibaren karmaşık :-)

+0

Bu karmaşık değil. Bu aşırı karmaşık bir * yapıdır *. – wildplasser

0
Sen libpq yok

, sadece

#!/bin/sh 
psql -U my_user mydb <<OMG 
    begin; 
    select tralal 1; 
    commit; 

    begin; 
    select domtidom 2; 
    commit; 
OMG 
+0

Herhangi bir şekilde bunun için% 100 gömülü SQL kullanabilirim ve 'psql' aracını kullanamıyorum? Örneğin, her iki sorguyu sunucuda yürütülen sorguları almak için gerekli olan sözdizimiyle sarılmış her ikisi de 2 seçimini yapmak için bir sorgu penceresinde Postico GUI (veya pgAdmin III) kullanın. (& İlk sorgunun sonuçları istemciye iade edilmek zorunda değildir) –

+0

Evet, libpq temel alınarak bir ön ek yapı oluşturabilirsiniz. Sadece yorumları filtreleyin, bir sonraki ';' yazın ve gönderin (dizelerden sakının!) Ve sonuçları alın ve onları atın. Hazırlanan sorgulara parametreleri aktarmak biraz daha zor olacaktır. Ama bütün bunlar temelde tam olarak ne 'psql dbname /dev/null' yapar. – wildplasser

+0

Ve birden çok ifadeye izin vermek istiyorsanız ** "OLUŞTURMA **"; 'arası sonlandırma, en az bir ayrıştırıcı türüne gereksiniminiz olacaktır (SQL LL (1) değil, bu yüzden bu güzel bir görev olmayacaktır. Belki bir 3. sipariş Markov-filtre işe yarayabilir) İyi şanslar! – wildplasser

İlgili konular