2010-06-03 107 views
2

我已經使用copy from命令填充了一個表,然後它將在彙總表中創建記錄。在複製命令成功運行後,在摘要表中看不到任何記錄。任何人都可以對我有所瞭解?請找到表以及下面的存儲過程: -觸發器沒有通過使用命令拷貝來觸發

CREATE TABLE apache_log (
     log_name character varying(255), 
     line integer, 
     client_address character varying(255), 
     rfc1413 character varying(32), 
     user_name character varying(32), 
     local_time timestamp with time zone, 
     log_date date, 
     log_hour smallint, 
     tenminute_bucket smallint, 
     fiveminute_bucket smallint, 
     method character varying(10), 
     url character varying(8192), 
     protocol character varying(10), 
     status_code smallint, 
     bytes_sent integer, 
     referer character varying(8192), 
     agent character varying(8192), 
     canon_name character varying(512) 
); 

CREATE INDEX apache_log_local_time ON apache_log USING btree (local_time); 
CREATE INDEX apache_log_client_address ON apache_log USING btree (client_address); 
CREATE INDEX apache_log_user_name ON apache_log USING btree (user_name); 
CREATE INDEX apache_log_canon_name ON apache_log USING btree (canon_name); 
CREATE INDEX apache_log_url ON apache_log USING btree (url); 
CREATE INDEX apache_log_method ON apache_log USING btree (method); 
CREATE INDEX apache_log_status_code ON apache_log USING btree (status_code); 
CREATE UNIQUE INDEX apache_log_name_line ON apache_log (log_name, line); 

CREATE TABLE tenminute_summary (
     log_date date, 
     log_hour smallint, 
     bucket smallint, 
     hit integer, 
     bytes_sent bigint, 
     status_code smallint 
); 

CREATE INDEX tenminute_summary_log_date_log_hour_bucket ON tenminute_summary (log_date, log_hour, bucket); 
CREATE UNIQUE INDEX tenminute_summary_log_date_log_hour_bucket_status_code ON tenminute_summary (log_date, log_hour, bucket, status_code); 

CREATE TABLE fiveminute_summary (
     log_date date, 
     log_hour smallint, 
     bucket smallint, 
     hit integer, 
     bytes_sent bigint, 
     status_code smallint 
); 

CREATE INDEX fiveminute_summary_log_date_log_hour_bucket ON fiveminute_summary (log_date, log_hour, bucket); 
CREATE UNIQUE INDEX fiveminute_summary_log_date_log_hour_bucket_status_code ON fiveminute_summary (log_date, log_hour, bucket, status_code); 

CREATE OR REPLACE FUNCTION update_history(history_log_date date, history_log_hour smallint, history_status_code smallint, history_fiveminute_bucket smallint, history_tenminute_bucket smallint, history_fiveminute_bytes_sent bigint, history_fiveminute_hit integer, history_fiveminute_bytes_sent bigint, history_fiveminute_hit integer) RETURNS INTEGER AS 
$update_history$ 
     BEGIN 
       IF (history_fiveminute_bucket IS NOT NULL) THEN 
         <<fiveminute_update>> 
         LOOP 
           UPDATE fiveminute_summary 
            SET bytes_sent = bytes_sent + history_fiveminute_bytes_sent, 
               hit = hit + history_fiveminute_hit 
             WHERE log_date = history_log_date AND 
                 log_hour = history_log_hour AND 
                 bucket = history_fiveminute_bucket AND 
                 status_code = history_status_code; 
           EXIT fiveminute_update WHEN found; 
           BEGIN 
             INSERT INTO fiveminute_summary (
               log_date, 
               log_hour, 
               bucket, 
               status_code, 
               bytes_sent, 
               hit) 
             VALUES (
               history_log_date, 
               history_log_hour, 
               history_fiveminute_bucket, 
               history_status_code, 
               history_fiveminute_bytes_sent, 
               history_fiveminute_hit); 
             EXIT fiveminute_update; 
           EXCEPTION 
             WHEN UNIQUE_VIOLATION THEN 
               -- do nothing 
           END; 
         END LOOP fiveminute_update; 
       END IF; 
       IF (history_tenminute_bucket IS NOT NULL) THEN 
         <<tenminute_update>> 
         LOOP 
           UPDATE tenminute_summary 
            SET bytes_sent = bytes_sent + history_tenminute_bytes_sent, 
               hit = hit + history_tenminute_hit 
             WHERE log_date = history_log_date AND 
                 log_hour = history_log_hour AND 
                 bucket = history_tenminute_bucket AND 
                 status_code = history_status_code; 
           EXIT tenminute_update WHEN found; 
           BEGIN 
             INSERT INTO tenminute_summary (
               log_date, 
               log_hour, 
               bucket, 
               status_code, 
               bytes_sent, 
               hit) 
             VALUES (
               history_log_date, 
               history_log_hour, 
               history_tenminute_bucket, 
               history_status_code, 
               history_tenminute_bytes_sent, 
               history_tenminute_hit); 
             EXIT tenminute_update; 
           EXCEPTION 
             WHEN UNIQUE_VIOLATION THEN 
               -- do nothing 
           END; 
         END LOOP tenminute_update; 
       END IF; 
       RETURN 0; 
     END; 
$update_history$ 
LANGUAGE plpgsql; 

CREATE OR REPLACE FUNCTION update_apache_log() RETURNS TRIGGER AS $update_apache_log$ 
     DECLARE 
       history_log_date date := null; 
       history_log_hour smallint := null; 
       history_status_code smallint := null; 
       history_fiveminute_bucket smallint := null; 
       history_tenminute_bucket smallint := null; 
       history_fiveminute_bytes_sent bigint := null; 
       history_fiveminute_hit integer := null; 
       history_tenminute_bytes_sent bigint := null; 
       history_tenminute_hit integer := null; 
       future_log_date date := null; 
       future_log_hour smallint := null; 
       future_status_code smallint := null; 
       future_fiveminute_bucket smallint := null; 
       future_tenminute_bucket smallint := null; 
       future_fiveminute_bytes_sent bigint := null; 
       future_fiveminute_hit integer := null; 
       future_tenminute_bytes_sent bigint := null; 
       future_tenminute_hit integer := null; 
       dummy integer := 0; 
     BEGIN 
       IF (TG_OP = 'DELETE') THEN 
         history_log_date        := OLD.log_date; 
         history_log_hour        := OLD.log_hour; 
         history_fiveminute_bucket    := OLD.fiveminute_bucket; 
         history_tenminute_bucket    := OLD.tenminute_bucket; 
         history_status_code        := OLD.status_code; 
         history_fiveminute_bytes_sent := 0 - OLD.bytes_sent; 
         history_fiveminute_hit     := -1; 
         history_tenminute_bytes_sent := 0 - OLD.bytes_sent; 
         history_tenminute_hit     := -1; 
         dummy:=update_history(history_log_date, history_log_hour, history_status_code, history_fiveminute_bucket, history_tenminute_bucket, history_fiveminute_bytes_sent, history_fiveminute_hit, history_fiveminute_bytes_sent, history_fiveminute_hit); 
         RETURN OLD; 
       ELSIF (TG_OP = 'INSERT') THEN 
         NEW.log_date         := extract(date from NEW.log_date AT TIME ZONE 'GMT+8'); 
         NEW.log_hour         := extract(hour from NEW.log_date AT TIME ZONE 'GMT+8'); 
         NEW.fiveminute_bucket     := floor(extract(minute from NEW.log_date AT TIME ZONE 'GMT+8')/5); 
         NEW.tenminute_bucket     := floor(extract(minute from NEW.log_date AT TIME ZONE 'GMT+8')/10); 
         future_log_date         := NEW.log_date; 
         future_log_hour         := NEW.log_hour; 
         future_status_code        := NEW.status_code; 
         future_fiveminute_bucket    := NEW.fiveminute_bucket; 
         future_tenminute_bucket     := NEW.tenminute_bucket; 
         future_fiveminute_bytes_sent := NEW.bytes_sent; 
         future_fiveminute_hit     := 1; 
         future_tenminute_bytes_sent    := NEW.bytes_sent; 
         future_tenminute_hit     := 1; 
         dummy:=update_history(future_log_date, future_log_hour, future_status_code, future_fiveminute_bucket, future_tenminute_bucket, future_fiveminute_bytes_sent, future_fiveminute_hit, future_fiveminute_bytes_sent, future_fiveminute_hit); 
         RETURN NEW; 
       ELSIF (TG_OP = 'UPDATE') THEN 
         IF (NEW.log_date <> OLD.log_date) THEN 
           NEW.date          := extract(date from NEW.log_date AT TIME ZONE 'GMT+8'); 
           NEW.hour          := extract(hour from NEW.log_date AT TIME ZONE 'GMT+8'); 
           NEW.fiveminute_bucket   := floor(extract(minute from NEW.log_date AT TIME ZONE 'GMT+8')/5); 
           NEW.tenminute_bucket   := floor(extract(minute from NEW.log_date AT TIME ZONE 'GMT+8')/10); 
           history_log_date      := OLD.log_date; 
           history_log_hour      := OLD.log_hour; 
           history_fiveminute_bucket  := OLD.fiveminute_bucket; 
           history_tenminute_bucket  := OLD.tenminute_bucket; 
           history_status_code      := OLD.status_code; 
           IF (OLD.status_code = NEW.status_code) THEN 
             history_fiveminute_bytes_sent := 0 - OLD.bytes_sent; 
             history_fiveminute_hit     := -1; 
             history_tenminute_bytes_sent := 0 - OLD.bytes_sent; 
             history_tenminute_hit     := -1; 
             future_log_date        := NEW.log_date; 
             future_log_hour        := NEW.log_hour; 
             future_status_code       := NEW.status_code; 
             future_fiveminute_bucket    := NEW.fiveminute_bucket; 
             future_tenminute_bucket     := NEW.tenminute_bucket; 
             future_fiveminute_bytes_sent := NEW.bytes_sent; 
             future_fiveminute_hit     := 1; 
             future_tenminute_bytes_sent    := NEW.bytes_sent; 
             future_tenminute_hit     := 1; 
             dummy:=update_history(future_log_date, future_log_hour, future_status_code, future_fiveminute_bucket, future_tenminute_bucket, future_fiveminute_bytes_sent, future_fiveminute_hit, future_fiveminute_bytes_sent, future_fiveminute_hit); 
           ELSE 
             IF (OLD.fiveminute_bucket = NEW.fiveminute_bucket AND OLD.log_date = NEW.log_date AND OLD.log_hour = OLD.log_hour) THEN 
               history_fiveminute_bytes_sent := NEW.bytes_sent - OLD.bytes_sent; 
               history_tenminute_bytes_sent := NEW.bytes_sent - OLD.bytes_sent; 
               history_tenminute_hit    := 0; 
             ELSE 
               history_fiveminute_bytes_sent := 0 - OLD.bytes_sent; 
               history_fiveminute_hit    := -1; 
               future_log_date        := NEW.log_date; 
               future_log_hour        := NEW.log_hour; 
               future_status_code       := NEW.status_code; 
               future_fiveminute_bucket    := NEW.fiveminute_bucket; 
               future_fiveminute_bytes_sent := NEW.bytes_sent; 
               future_fiveminute_hit    := 1; 
               IF (OLD.tenminute_bucket = NEW.tenminute_bucket) THEN 
                 history_tenminute_bytes_sent := NEW.bytes_sent - OLD.bytes_sent; 
                 history_tenminute_hit    := 0; 
               ELSE 
                 history_tenminute_bytes_sent := 0 - OLD.bytes_sent; 
                 history_tenminute_hit    := -1; 
                 future_tenminute_bucket    := NEW.tenminute_bucket; 
                 future_tenminute_bytes_sent   := NEW.bytes_sent; 
                 future_tenminute_hit     := 1; 
               END IF; 
               dummy:=update_history(future_log_date, future_log_hour, future_status_code, future_fiveminute_bucket, future_tenminute_bucket, future_fiveminute_bytes_sent, future_fiveminute_hit, future_fiveminute_bytes_sent, future_fiveminute_hit); 
             END IF; 
           END IF; 
         ELSE 
           history_log_date        := OLD.log_date; 
           history_log_hour        := OLD.log_hour; 
           history_status_code        := OLD.status_code; 
           history_fiveminute_bucket    := OLD.fiveminute_bucket; 
           history_tenminute_bucket    := OLD.tenminute_bucket; 
           IF (OLD.status_code <> NEW.status_code) THEN 
             history_fiveminute_bytes_sent := 0 - OLD.bytes_sent; 
             history_fiveminute_hit     := -1; 
             history_tenminute_bytes_sent := 0 - OLD.bytes_sent; 
             history_tenminute_hit     := -1; 
             future_log_date        := NEW.log_date; 
             future_log_hour        := NEW.log_hour; 
             future_status_code       := NEW.status_code; 
             future_fiveminute_bucket    := NEW.fiveminute_bucket; 
             future_tenminute_bucket     := NEW.tenminute_bucket; 
             future_fiveminute_bytes_sent   := NEW.bytes_sent; 
             future_fiveminute_hit     := 1; 
             future_tenminute_bytes_sent    := NEW.bytes_sent; 
             future_tenminute_hit     := 1; 
             dummy:=update_history(future_log_date, future_log_hour, future_status_code, future_fiveminute_bucket, future_tenminute_bucket, future_fiveminute_bytes_sent, future_fiveminute_hit, future_fiveminute_bytes_sent, future_fiveminute_hit); 
           ELSIF (OLD.bytes_sent <> NEW.bytes_sent) THEN 
             history_fiveminute_bytes_sent := NEW.bytes_sent - OLD.bytes_sent; 
             history_tenminute_bytes_sent := NEW.bytes_sent - OLD.bytes_sent; 
           END IF; 
         END IF; 
         dummy:=update_history(history_log_date, history_log_hour, history_status_code, history_fiveminute_bucket, history_tenminute_bucket, history_fiveminute_bytes_sent, history_fiveminute_hit, history_fiveminute_bytes_sent, history_fiveminute_hit); 
         RETURN NEW; 
       END IF; 
       RETURN NULL; 
     END; 
$update_apache_log$ LANGUAGE plpgsql; 

CREATE TRIGGER update_apache_log 
     BEFORE INSERT OR UPDATE OR DELETE ON apache_log 
     FOR EACH ROW EXECUTE PROCEDURE update_apache_log(); 
+0

在您的新記錄中,「fiveminute_bucket」和「tenminute_bucket」是否都爲NULL? – 2010-06-03 04:37:44

回答

1

功能update_history使用兩個參數具有相同的名稱兩次:

ERROR: parameter name "history_fiveminute_bytes_sent" used more than once 
SQL status:42P13 

參見:

CREATE OR REPLACE FUNCTION update_history(
    history_log_date date, 
    history_log_hour smallint, 
    history_status_code smallint, 
    history_fiveminute_bucket smallint, 
    history_tenminute_bucket smallint, 
    history_fiveminute_bytes_sent bigint, <=== See errormessage 
    history_fiveminute_hit integer,   <=== And this one as well 
    history_fiveminute_bytes_sent bigint, <=== 
    history_fiveminute_hit integer    <=== 
) RETURNS INTEGER AS 

的PostgreSQL 9.0測試版不喜歡這個,它沒有任何意義。舊版本可能沒有抱怨,但可能與執行有相同的問題。你檢查了錯誤日誌嗎?

並在這兩個函數中提示通知,以查看觸發器是否已激活。

RAISE NOTICE 'function X is doing something'; 
0

我發現很多錯誤,而Postgresql 8.4根本沒有投訴。無論如何,我已經放棄了存儲過程的方法,並決定使用sql直接填充表格,因爲我正以非常特殊的方式對錶格進行批量更新。同樣使用sql填充表格在整個過程花費的時間方面效率更高。