Có thể cast enum thành số nguyên không? Bắt đầu từ 1 phần tử đầu tiênPostgreSQL: Có thể cast enum thành số nguyên không?
Trả lời
Mặc dù bạn không thể truyền enum thành số nguyên như Catcall giải thích, bạn có thể sử dụng bảng danh mục hệ thống pg_enum
tương thích với PostgreSQL cụ thể và không phiên bản để có được đại diện thứ tự.
regress=# CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
regress=# select enumsortorder, enumlabel from pg_catalog.pg_enum
regress-# WHERE enumtypid = 'happiness'::regtype ORDER BY enumsortorder;
enumsortorder | enumlabel
---------------+------------
1 | happy
2 | very happy
3 | ecstatic
(3 rows)
Điều này có vẻ dễ dàng, nhưng không phải vậy. Quan sát:
regress=# ALTER TYPE happiness ADD VALUE 'sad' BEFORE 'happy';
regress=# ALTER TYPE happiness ADD VALUE 'miserable' BEFORE 'very happy';
regress=# SELECT * FROM pg_enum ;
enumtypid | enumsortorder | enumlabel
-----------+---------------+------------
185300 | 1 | happy
185300 | 2 | very happy
185300 | 3 | ecstatic
185300 | 0 | sad
185300 | 1.5 | miserable
(5 rows)
Từ đây bạn có thể thấy rằng enumsortorder
cung cấp thứ tự, nhưng không cố định 'khoảng cách'. Nếu hỗ trợ cho việc loại bỏ các giá trị từ enums được thêm vào, nó sẽ có khả năng tạo ra 'lỗ' trong trình tự, quá.
Để có được vị trí enum, bạn sẽ cần sử dụng chức năng cửa sổ row_number()
để nhận đơn đặt hàng và pg_typeof
để nhận số oid
(regtype
) của loại enum. Bạn cần điều này để đảm bảo rằng bạn trả lại đúng thứ tự khi có nhiều enums với cùng một nhãn.
Chức năng này không được công việc:
CREATE OR REPLACE FUNCTION enum_to_position(anyenum) RETURNS integer AS $$
SELECT enumpos::integer FROM (
SELECT row_number() OVER (order by enumsortorder) AS enumpos,
enumsortorder,
enumlabel
FROM pg_catalog.pg_enum
WHERE enumtypid = pg_typeof($1)
) enum_ordering
WHERE enumlabel = ($1::text);
$$ LANGUAGE 'SQL' STABLE STRICT;
Lưu ý:
- Đó là
STABLE
khôngIMMUTABLE
, bởi vì thêm (hoặc nếu hỗ trợ trong Thạc được sau bổ sung, loại bỏ) các giá trị từ enums sẽ thay đổi các chỉ số đặt hàng và phá vỡ dựa trên thứ tự; do đó - Bạn không thể sử dụng điều này trong biểu thức chỉ mục; và
- Đó là
STRICT
vì nó sẽ trả về null cho một đầu vào vô
Bây giờ bạn có thể sử dụng chức năng này để CREATE CAST
cho enums cụ thể để integer
. Bạn không thể tạo một diễn viên chung cho tất cả các enums thành integer
, vì không thể sử dụng loại giả anyenum
cho các phôi. Ví dụ, nếu tôi muốn cho phép bản demo happiness
được đúc để nguyên, tôi sẽ viết:
CREATE CAST (happiness AS integer) WITH FUNCTION enum_to_position(anyenum);
sau đó tôi có thể thực hiện thành công:
regress=# SELECT ('happy'::happiness)::integer;
int4
------
2
(1 row)
Lưu ý rằng đây có lẽ là một điên điều cần làm, không được hỗ trợ và rất có thể là một ý tưởng tồi tệ. Mã của bạn phải lưu ý rằng các giá trị thứ tự sẽ thay đổi khi bạn thêm hoặc (nếu sau này được hỗ trợ) xóa một giá trị khỏi enum.
Chỉ mục được tạo dựa trên dàn diễn viên này (chỉ có thể nếu hàm được định nghĩa bất biến) sẽ bắt đầu tạo ra kết quả điên và sai nếu bạn thay đổi định nghĩa của enum (ngoại trừ bằng cách thêm giá trị mới vào cuối) vì PostgreSQL tin bạn khi bạn nói một hàm là bất biến. Đừng làm thế.
Bạn không thể đúc một enum thành số nguyên.
Bạn có thể có thể viết số custom operator để trích xuất số được liên kết với giá trị, nhưng tôi thấy khó tin rằng điều đó đáng để gây rắc rối.
Nếu tôi cần loại thông tin đó, tôi đã xây dựng một bảng và đặt tham chiếu khóa ngoài cho nó thay vì sử dụng enum.
Bạn có thể thực hiện việc này thông qua việc lạm dụng thông minh chức năng enum_range().
Nếu bạn chuyển giá trị enum của bạn làm đối số thứ hai của hàm enum_range(), với NULL là giá trị đầu tiên, bạn sẽ nhận được một mảng với tất cả các giá trị mà enum có thể lấy đến điểm đó. Sau đó, bạn chỉ cần đếm chúng với array_length và bạn nhận được một số nguyên đại diện cho enum.
Đây là một ví dụ. Đây là enum của tôi:
content=# select enum_range(null::content_state);
enum_range
--------------------------------------------------------------
{created,deleted,preview,draft,submitted,approved,published}
Và đây là tôi tìm ra int cho "dự thảo" Giá trị:
content=# select array_length(enum_range(NULL, 'draft'::content_state), 1);
array_length
--------------
4
Nên biết trước: loại bỏ các giá trị từ enum sẽ làm cho điểm ints của bạn để giá trị khác, do đó, không sử dụng điều này trên enums mà bạn có thể muốn thay đổi tại một số điểm.
Có thể.
Nếu loại enum của bạn chỉ chứa giá trị số nguyên thì việc truyền trở nên rất đơn giản. Giả sử tôi có một kiểu enum như: - Create type monthenum as enum ('7', '8', '9', '10', '11', '12', '1', '2', '3', '4', '5', '6');
Bây giờ bạn có thể sử dụng đúc các giá trị enum để nguyên và hiển thị chúng như kỷ lục riêng biệt như sau: -
select (unnest(enum_range(null::monthenum))::text)::integer as monthvalue
Hy vọng điều này sẽ giúp bạn, Ý tưởng là bạn có thể chuyển đổi enum thành văn bản và sau đó lại thành bất kỳ loại tương thích nào khác của giá trị enum của bạn. Bạn cũng có thể sử dụng cho vòng lặp để chuyển đổi từng giá trị.
- 1. Postgresql. TẠO CAST 'nhân vật thay đổi' thành 'số nguyên'
- 2. Có thể truyền số nguyên thành enum không?
- 3. MySQL Cast NULL thành số nguyên 0
- 4. Không thể (hoặc có thể) vào Danh sách <int> .Cast <Enum>()?
- 5. Reinterpret cast floating point number thành số nguyên
- 6. Cast Int to Generic Enum trong C#
- 7. Nâng cấp một cột VARCHAR thành loại enum trong postgresql
- 8. java.lang.ClassCastException: android.app.Application không thể được cast thành roboguice.application.RoboApplication
- 9. Sử dụng enum làm hằng số nguyên trong C#
- 10. Lấy giá trị số nguyên từ enum
- 11. PostgreSQL - ALTER kiểu dữ liệu cột từ số nguyên để nguyên mảng
- 12. Có thể lấy tên và giá trị của các thành viên của enum trong D không?
- 13. Rails Migration: Bigint trên PostgreSQL có vẻ không thành công?
- 14. QByteArray thành số nguyên
- 15. Chuyển đổi một Integer để Enum trong PostgreSQL
- 16. Bài tập làm cho con trỏ từ số nguyên mà không cần cast
- 17. Làm cách nào để chuyển đổi một ký tự thành số nguyên trong một hàm PostgreSQL (9.1)?
- 18. Clojure: Integer không thể cast để IFN
- 19. Chuyển đổi chuỗi có chứa một số thành số nguyên
- 20. Tôi có thể sử dụng C-preprocssor để chuyển đổi một số nguyên thành chuỗi không?
- 21. PHP kiểm tra xem đối tượng có thể được chuyển đổi thành số nguyên không?
- 22. Biến NSString thành số nguyên
- 23. Java Chuyển đổi số nguyên thành số nguyên hex
- 24. Argv - Chuỗi thành số nguyên
- 25. Tràn Python Lỗi: không thể vừa với 'dài' thành số nguyên chỉ số =
- 26. số nguyên ruby thành boolean
- 27. Tôi có thể làm gì với biến số enum?
- 28. Chuyển chuỗi thành số nguyên
- 29. Chuyển đổi số được viết thành từ thành số nguyên?
- 30. Có thể ghi số nguyên bằng số không bằng các biểu thức chính quy không?