programing

MariaDB에서 트리거 starts에 배치된 함수는 다른 값을 반환합니다.

testmans 2023. 7. 9. 10:36
반응형

MariaDB에서 트리거 starts에 배치된 함수는 다른 값을 반환합니다.

다음과 같은 테이블과 함수가 있습니다.

CREATE TABLE `test` (`ID` BINARY(16)) ENGINE=InnoDB;

CREATE FUNCTION `UUID_ENCODE`(`uuid` CHAR(36))
    RETURNS binary(16)
    DETERMINISTIC
BEGIN
    RETURN UNHEX(REVERSE(REPLACE(uuid,'-','')));
END

CREATE FUNCTION `UUID_DECODE`(`uuid` BINARY(16))
    RETURNS char(36)
    DETERMINISTIC
BEGIN
RETURN LOWER(CONCAT_WS('-',
    REVERSE(HEX(RIGHT(uuid,6))),
    REVERSE(HEX(MID(uuid,9,2))),
    REVERSE(HEX(MID(uuid,7,2))),
    REVERSE(HEX(MID(uuid,5,2))),
    REVERSE(HEX(LEFT(uuid,4)))
));
END

삽입이 올바르게 작동합니다.

INSERT INTO test (ID) VALUES(UUID_ENCODE('323febe6-cd89-4773-a46c-aab794fb7cbc'));

SELECT UUID_DECODE(ID) FROM test;
+--------------------------------------+
| uuid_decode(id)                      |
+--------------------------------------+
| 323febe6cd89-4773-a46c-aab7-94fb7cbc |
+--------------------------------------+

트리거를 생성하기만 하면 됩니다.

CREATE TRIGGER `test_uuid_encode` BEFORE INSERT ON `test` FOR EACH ROW BEGIN
    SET NEW.ID = UUID_ENCODE(NEW.ID);
END

테이블에서 반절단 값을 가져옵니다.

INSERT INTO test (ID) VALUES('323febe6-cd89-4773-a46c-aab794fb7cbc');

Warning (Code 1265): Data truncated for column 'ID' at row 1

SELECT UUID_DECODE(ID) FROM test;
+--------------------------------------+
| uuid_decode(id)                      |
+--------------------------------------+
| 000000000000-0000-0032-3feb-e6cd8947 |
+--------------------------------------+

이 트리거의 문제점은 무엇입니까?

소프트웨어 버전:

ver 5.5.33a-MariaDB for Win64 on x86 (mariadb.org 이진 배포)

ID테이블의 열이 다음과 같이 선언됩니다.BINARY(16)그리고 당신의UUID_ENCODE을 기대합니다.CHAR(36)호출할 때UUID_ENCODE트리거 없이 바로 작동하며 36자 문자열을 올바르게 수신합니다.트리거를 대신 사용하면 삽입하는 값이 먼저 열의 유형으로 변환됩니다.NEW.ID의 결과를 포함할 것입니다.CAST('323febe6-cd89-4773-a46c-aab794fb7cbc' AS BINARY(16)트리거가 함수를 호출하면 다음 값을 다시 캐스팅합니다.NEW.ID사용자의 기능에 의해 예상되는 유형으로.이것이 함수가 얻게 되는 값입니다.

SELECT CAST(CAST('323febe6-cd89-4773-a46c-aab794fb7cbc' AS BINARY(16)) AS CHAR);

323febe6-cd89-47

보시다시피 함수는 잘린 값을 수신합니다.결과는 다음과 같습니다.

SELECT UUID_DECODE(UUID_ENCODE('323febe6-cd89-47'));

000000000000-0000-0032-3feb-e6cd8947

갱신하다

트리거에서 원하는 기능을 구현하는 한 가지 방법은 함수가 예상하는 유형으로 더미 null 가능 열을 추가하는 것입니다.

CREATE TABLE test (ID BINARY(16) KEY DEFAULT 0, CHARID CHAR(36) NULL);

CREATE TRIGGER test_uuid_encode BEFORE INSERT ON test FOR EACH ROW BEGIN
    SET NEW.ID = UUID_ENCODE(NEW.CHARID)
      , NEW.CHARID = NULL;
END

이러한 방법으로 다음을 수행할 수 있습니다.

INSERT test (CHARID) VALUES ('323febe6-cd89-4773-a46c-aab794fb7cbc');

SELECT UUID_DECODE(ID) FROM test;
+--------------------------------------+
| uuid_decode(id)                      |
+--------------------------------------+
| 323febe6cd89-4773-a46c-aab7-94fb7cbc |
+--------------------------------------+

여기에 바이올린을 만들었습니다.

참고:

  • 비록 ~일지라도CHARIDNULL을 허용합니다.ID그렇지 않습니다. 따라서 NULL 값을 삽입하려고 합니다.CHARID트리거가 설정을 시도할 수 있습니다.ID삽입이 거부되고 NULL이 됩니다.
  • 잘못된 값을 에 삽입하려고 시도하는 중CHARID그것이 원인이UUID_ENCODENULL을 반환하는 것도 실패합니다.
  • DEFAULT 0에 대한 조항.ID삽입 목록에서 열을 생략할 수 있습니다.테이블에 기록되는 값은 항상 트리거에 의해 생성되는 값입니다.
  • 항상 NULL인 null 가능한 열은 테이블 레이아웃 및 행 형식에 따라 행당 0-2바이트의 추가 스토리지를 사용해야 합니다(예를 들어 다음과 같은 경우는 피해야 합니다).FIXEDMyISAM 엔진의 형식).
  • 다양한 변형이 가능합니다.추가 스토리지를 사용해도 상관없다면 스토리지를CHARID값을 NULL로 설정하지 않습니다.이진을 명시적으로 삽입할 수 있도록 하려면ID트리거에 체크를 추가하여 계산할 수 있는 값NEW.ID0 등인 경우에만
  • 허용되는 경우 UPDATE 작업에 대해 유사한 트리거가 있어야 합니다.

언급URL : https://stackoverflow.com/questions/19033874/in-mariadb-function-placed-in-a-trigger-starts-returns-a-different-value

반응형