Loại chuyển đổi với giá trị dự phòng mặc định


12

Trong PostgreSQL (8.4), tôi đang cố gắng chuyển đổi một tham số chuỗi thành một ngày trong truy vấn SQL, quay trở lại now()khi chuỗi không phải là một ngày hợp lệ (hoặc trống).

Trong "pseudo-SQL", đây sẽ là một cái gì đó như thế này:

SELECT CASE WHEN ? is not a valid date THEN now()::DATE ELSE CAST(? AS DATE) END;

Tôi đã cố gắng đơn giản hóa vấn đề để phát hiện một chuỗi trống bằng hai truy vấn sau:

SELECT CASE WHEN ?='' THEN now()::DATE ELSE CAST(? AS DATE) END;
SELECT DATE(CASE WHEN ?='' THEN now() ELSE ?  END);

Ví dụ: nếu tham số là '', thì điều này tương đương với điều này:

SELECT CASE WHEN ''='' THEN now()::DATE ELSE CAST('' AS DATE) END;
SELECT DATE(CASE WHEN ''='' THEN now() ELSE ''  END);

Cả hai đều thất bại với ERROR: invalid input syntax for type timestamp with time zone: "" Nó có ý nghĩa, nhưng nó ngụ ý rằng ELSEkhối được đánh giá (hoặc ít nhất là các loại của nó được giải quyết) cho dù CASEđiều kiện có đúng hay không . Các công việc sau đây, nhưng điều tôi muốn CASExử lý (hoặc tương tự) để xử lý, chính xác là trường hợp khi đó không phải là ngày hợp lệ.

SELECT CASE WHEN '2011-12-01'='' THEN now()::DATE ELSE CAST('2011-12-01' AS DATE) END;

Gần nhất tôi có một giải pháp làm việc là thế này:

SELECT DATE(COALESCE(NULLIF(?, '')::timestamptz, now()));

Trong trường hợp này, nếu tham số là '', nó trả về ngày hiện tại, nếu không, nó sẽ trả về ngày được truyền trong tham số chuỗi (miễn là nó có thể được chuyển thành ngày hợp lệ).

Những gì tôi muốn là tiến thêm một bước và làm cho bất cứ điều gì không thể được chuyển thành DATEsử dụng ngày hiện tại. Tôi đoán điều này có thể được thực hiện bằng cách sử dụng hàm PL / pgQuery tùy chỉnh sẽ khắc phục lỗi này , nhưng điều này có thể được thực hiện mà không có chức năng như vậy, trong SQL "đơn giản" (hoặc ít nhất là sử dụng các hàm PostgreQuery hiện có)?

Câu trả lời:


6

Bạn không thể xử lý các trường hợp ngoại lệ SQL trong một câu lệnh SQL như bạn có thể từ bên trong PL / pgSQL .

Bạn phải viết một chức năng tùy chỉnh như bạn đề xuất, ví dụ:

create function is_valid_date(text) returns boolean language plpgsql immutable as $$
begin
  return case when $1::date is null then false else true end;
exception when others then
  return false;
end;$$;

kiểm tra:

with w as (select 'asdsad'::text dt1, '2011-12-01'::text dt2, null::text dt3)
select case when is_valid_date(dt1) then dt1::date else current_date end d1,
       case when is_valid_date(dt2) then dt2::date else current_date end d2,
       case when is_valid_date(dt3) then dt3::date else current_date end d3
from w;

     d1     |     d2     |     d3
------------+------------+------------
 2011-12-06 | 2011-12-01 | 2011-12-06

tín dụng cho bài đăng danh sách gửi thư này
Jack nói hãy thử topanswers.xyz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.