경험이 풍부한 새로운 고객을 위한 Oracle Gotchas
일반적으로 관계형 데이터베이스(MySQL, MS SQL Server, Postgres 등)는 아니지만 플랫폼에는 새로 온 사용자를 위한 Oracle gotchas는 무엇입니까?
제가 찾고 있는 것의 두 가지 예는
많은 관계형 데이터베이스 제품은 사용자를 위해 auto_increment 키 생성을 처리합니다.Oracle이 그렇지 않습니다. 시퀀스를 수동으로 생성한 다음 트리거를 생성해야 합니다.
SQL Developer 인터페이스를 통해 데이터를 삽입할 때는 데이터를 수동으로 커밋해야 합니다.
PHP 관련 gotchas에 대한 보너스 포인트, 그것이 플랫폼이기 때문에 이 가상의 경험이 풍부한 newb가 사용할 것입니다.
참고: 여기서는 gotchas만 설명하고 있습니다. 즉, 다음과 같은 상황입니다.Oracle다른 시스템처럼 작동하지 않습니다.Oracle다른 것들보다 많은 이점을 가지고 있습니다.RDBMS의 주제가 , 하만그주아제닙다니가게의시물.
은 다니없습.
SELECT없이FROM.SELECT 1실패할 경우 다음 작업을 수행해야 합니다.
SELECT 1 FROM dual과 " " " "
NULL같은 것입니다.SELECT * FROM dual WHERE '' = ''아무것도 반환하지 않습니다.
다 없어요.
TOP도 아니다LIMIT에서 합니다.WHERE절:SELECT * FROM ( SELECT * FROM mytable ORDER BY col ) WHERE rownum < 10정확히 이런 식으로, 서브쿼리를 사용한 이후로.
ROWNUM가 앞에ORDER BY.상관된 하위 쿼리를 한 수준 이상 깊이 중첩할 수 없습니다.이 작업은 실패합니다.
SELECT ( SELECT * FROM ( SELECT dummy FROM dual di WHERE di.dummy = do.dummy ORDER BY dummy ) WHERE rownum = 1 ) FROM dual do이것이 문제가 된다.
NULL값이 인덱싱되지 않았습니다.과 같은 하여 주문하지 않습니다.SELECT * FROM ( SELECT * FROM mytable ORDER BY col ) WHERE rownum < 10,~하지 않는 한
col는 로표됩니다로 되어 있습니다.NOT NULL.주목할 만한 것은
NULL열이 아니라 인덱스되지 않은 값입니다.null 가능한 열에 인덱스를 생성할 수 있습니다.NULL값이 인덱스에 들어갑니다.에서 " 나쿼리조다음과같이가때사않인다습용니지되는덱스그정할러건이▁that▁will다▁index"로 가정할 때는 인덱스가
NULL가치는 아마도 그것을 만족시킬 수 있습니다.(" " " " " " " ( " " " " " " 포함).
NULL. 못합니다 그렇다면 인덱스는 non-에 대해 알지 못합니다.NULL따라서 값을 검색할 수 없습니다.SELECT * FROM ( SELECT * FROM mytable ORDER BY col ) WHERE rownum < 10그러나 이 쿼리는 다음 인덱스를 사용합니다.
SELECT * FROM ( SELECT * FROM mytable WHERE col IS NOT NULL ORDER BY col ) WHERE rownum < 10가 아닌 때부터
NULL값은 조건을 충족할 수 없습니다.기적으로본,
NULL는 첫 번째가 마지막으로 됩니다( 정 다니렬됩로으막는지아마첫닌째번가예▁in▁s(:▁s다니정됩렬like▁are▁last는▁sorted,로:PostgreSQL그러나 과는 달리MySQL그리고.SQL Server)다음 쿼리:
SELECT * FROM ( SELECT 1 AS id FROM dual UNION ALL SELECT NULL AS id FROM dual ) q ORDER BY id돌아올 것입니다
id --- 1 NULL정하기와 같이
SQL Server그리고.MySQL사용:SELECT * FROM ( SELECT 1 AS id FROM dual UNION ALL SELECT NULL AS id FROM dual ) q ORDER BY id NULLS FIRST깨짐에 유의
rownum하위 쿼리에서 후자를 사용하지 않는 경우(위에서 설명한 것과 동일),"MYTABLE"그리고."mytable"(큰따옴표가 중요함)는 서로 다른 개체입니다.SELECT * FROM mytable -- wihout quotes후자가 아닌 전자 중에서 선택할 것입니다.전자가 없으면 쿼리가 실패합니다.
CREATE TABLE mytable성
"MYTABLE",것은 아니다."mytable".Oracle모든 암묵적 잠금(이로 인해 발생합니다.DML운영)은 행 레벨이며 결코 에스컬레이션되지 않습니다.트랜잭션의 영향을 받지 않는 행은 암시적으로 잠글 수 없습니다.작가들은 결코 독자들을 차단하지 않습니다.
으로 .
LOCK TABLE진술.행 잠금은 데이터 페이지에 저장됩니다.
Oracle"없니다습"는CLUSTERED인덱스", "인덱스로 구성된 테이블"이 있습니다..SQL Server그리고.MySQL와 함께InnoDB).Oracle월드, "데이터베이스 스토리지"란 여러 테이블에서 공통 키를 공유하는 행이 데이터 페이지를 공유하도록 여러 테이블을 구성하는 것을 의미합니다.단일 데이터 페이지는 여러 테이블의 여러 행을 호스트하므로 이 키에 대한 조인 속도가 매우 빠릅니다.
1번을 선택하면 작동하지 않습니다. 대신 듀얼에서 1번을 선택하십시오.
계층형 데이터로 작업하는 경우 연결 기준이 좋습니다.
하나의 댓글:Sybase/SQL Server IDENTITY 열의 동작을 복제하는 것에 대해 확신하지 않는 한 시퀀스를 사용하기 위해 트리거를 생성할 필요가 없습니다.저는 시퀀스를 실제 삽입문에 직접 사용하는 것이 더 유용하다고 생각합니다.
INSERT
INTO MyTable
( KeyCol
, Name
, Value
)
SELECT Seq_MyTable.NextVal
, 'some name'
, 123
FROM dual;
트리거 실행의 오버헤드에 대해 걱정할 필요가 없으며, 스키마에서 다른 스키마로 데이터를 이동할 때와 같이 시퀀스 값이 할당될 필요 없이 테이블에 행을 삽입하는 작업을 유연하게 처리할 수 있습니다.IDENTITY 기능이 어렵거나 불가능하게 만드는 데이터 및 기타 기술 범위를 삽입하기 위해 시퀀스에서 값을 미리 선택할 수도 있습니다.
행 집합에서 null 값으로 완전히 채워질 수 있는 열 주위에 nvl(열)을 사용하는 것을 잊지 마십시오.그렇지 않으면 행 집합에서 열이 누락됩니다.
맞아요, 완전히 놓쳤어요!
예:
SELECT nvl(employeeName,'Archie'), nvl(employeeSpouse,'Edith') FROM Employee
이렇게 하면 행 집합의 모든 값이 null인 경우에도 행 집합에 두 개의 열이 표시됩니다.여러분은 그저 '아키'와 '에디스'의 가치들을 많이 보게 될 것입니다.nvl()을 사용하지 않으면 열을 하나만 얻거나 둘 다 되돌릴 수 없습니다.개발 환경에서 코드가 잘 실행되고 QA를 통과할 수도 있지만, 프로덕션 단계에서 테이블의 값이 결과의 구조를 바꿀 수도 있습니다.
즉, null 가능한 열을 선택할 때마다 nvl()을 사용해야 합니다.
SQL Server보다 스키마 개체와 데이터에 대소문자를 구분하는 Oracle 데이터베이스가 더 많습니다.
여기에 몇 가지 차이점을 적어 두었습니다.ANSI 표준 SQL이 데이터베이스 간에 완벽하게 이동할 수 있다고 생각하십니까? 다시 생각해 보세요.
임시 테이블
일반 테이블처럼 만들고 인덱싱하지만 모든 세션/트랜잭션은 자체 데이터만 봅니다.이것은 MS SQL과 다릅니다.
전역 변수
참조를 통해 전달됩니다.즉, 전역 변수를 모수로 프로시저에 전달하고 프로시저 내부의 전역 변수를 수정하면 모수 값도 변경됩니다.하지만 그다지 인기 있는 방법은 아닙니다.
트리거
매우 최근 버전까지 유사한 트리거가 발생할 방법을 결정할 수 있는 방법은 없었습니다.어떤 "각 행에 대한 업데이트 전"이 처음인지에 대해 정말로 관심이 있다면 모든 것을 하나의 트리거에 넣습니다.
MySQL과 같은 그룹 연결이 없습니다.만약 당신이 그룹 연결 집계 함수를 원한다면, 당신은 당신 자신의 것을 작성해야 합니다.다음은 제 구현입니다.
drop type T_GROUP_CONCAT;
create or replace type GROUP_CONCAT_PARAM as object
(
val varchar2(255),
separator varchar2(10),
numToConcat NUMBER,
MAP MEMBER FUNCTION GROUP_CONCAT_PARAM_ToInt return VARCHAR2
);
--map function needed for disctinct in select clauses
CREATE OR REPLACE TYPE BODY GROUP_CONCAT_PARAM IS
MAP MEMBER FUNCTION GROUP_CONCAT_PARAM_ToInt return VARCHAR2 is
begin
return val;
end;
end;
/
CREATE OR REPLACE TYPE T_GROUP_CONCAT
AS OBJECT (
runningConcat VARCHAR2(5000),
runningCount NUMBER,
STATIC FUNCTION ODCIAggregateInitialize
( actx IN OUT T_GROUP_CONCAT
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate
( self IN OUT T_GROUP_CONCAT,
val IN GROUP_CONCAT_PARAM
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate
( self IN T_GROUP_CONCAT,
returnValue OUT VARCHAR2,
flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge
(self IN OUT T_GROUP_CONCAT,
ctx2 IN T_GROUP_CONCAT
) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY T_GROUP_CONCAT AS
STATIC FUNCTION ODCIAggregateInitialize
( actx IN OUT T_GROUP_CONCAT
) RETURN NUMBER IS
BEGIN
IF actx IS NULL THEN
actx := T_GROUP_CONCAT ('', 0);
ELSE
actx.runningConcat := '';
actx.runningCount := 0;
END IF;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateIterate
( self IN OUT T_GROUP_CONCAT,
val IN GROUP_CONCAT_PARAM
) RETURN NUMBER IS
BEGIN
if self.runningCount = 0 then
self.runningConcat := val.val;
elsif self.runningCount < val.numToConcat then
self.runningConcat := self.runningConcat || val.separator || val.val;
end if;
self.runningCount := self.runningCount + 1;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateTerminate
( self IN T_GROUP_CONCAT,
ReturnValue OUT VARCHAR2,
flags IN NUMBER
) RETURN NUMBER IS
BEGIN
returnValue := self.runningConcat;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateMerge
(self IN OUT T_GROUP_CONCAT,
ctx2 IN T_GROUP_CONCAT
) RETURN NUMBER IS
BEGIN
self.runningConcat := self.runningConcat || ',' || ctx2.runningConcat;
self.runningCount := self.runningCount + ctx2.runningCount;
RETURN ODCIConst.Success;
END;
END;
/
CREATE OR REPLACE FUNCTION GROUP_CONCAT
( x GROUP_CONCAT_PARAM
) RETURN VARCHAR2
--PARALLEL_ENABLE
AGGREGATE USING T_GROUP_CONCAT;
/
사용 방법:
select GROUP_CONCAT(GROUP_CONCAT_PARAM(tbl.someColumn, '|', 2)) from someTable tbl
언급URL : https://stackoverflow.com/questions/1209039/oracle-gotchas-for-an-experienced-newb
'programing' 카테고리의 다른 글
| Oracle PL/SQL For Loop을 사용하여 쉼표로 구분된 문자열을 반복합니다. (0) | 2023.08.12 |
|---|---|
| ES6 화살표 기능에서 반환문을 사용해야 하는 경우 (0) | 2023.08.12 |
| 단일 구성 키에 대한 다중 값 (0) | 2023.08.07 |
| Android용 Spring Rest Template로 인증된 POST 요청 만들기 (0) | 2023.08.07 |
| Git: 'Git reset' 후 커밋 메시지를 재사용/유지하는 방법은 무엇입니까? (0) | 2023.08.07 |