2016-08-17 2 views
6

Oracle SQL 데이터베이스에서 실행되는 Business Objects를 사용하고 있습니다. PL 또는 모든 종류의 SQL 명령 줄에 액세스 할 수 없으며 데이터베이스에 대한 쓰기 권한이 없습니다. 쿼리를 하나의 명령으로 만 실행할 수 있으며 정의 된 열 집합을 출력해야합니다.Oracle SQL에서 날짜 (또는 문자열)로 사용자 프롬프트 전달

내가 같이 SQL에 나타나는 사용자 메시지에서 데이터 취할 수 있어요 : 내가 말할 수있는 예를 들어

@variable('Prompt1') 

:이 충분히 쉽게

SELECT 
    A.SomeDate 
FROM 
    A 
WHERE 
    A.SomeDate BETWEEN @variable('Start') AND @variable('End Date') 

. 그것은 작동한다; 사용자에게 날짜를 입력하도록 요청합니다. 그 (것)들을 포함하는 모든 성냥을 돌려 보낸다.

그러나 사용자는 Business Objects의 "Infoview"시스템을 사용하여 쿼리를 실행하고 프롬프트 시스템에 날짜 선택 도구가 표시됩니다. 기본적으로 날짜 부분 ("01/01/2016 12:00:00 AM ").

사용자가 시간 부분을 삭제하지 않으면 SomeDate 값이 선택한 시간을 벗어나면 레코드가 누락 될 수 있습니다. 예를 들어, 오늘의 모든 기록을 갖고 싶다면 기술적으로 00:00:00 (자정)에서 23:59:59 사이의 모든 것을 원합니다.

WHERE 
    A.SomeDate BETWEEN TRUNC(@variable('Start')) AND TRUNC(@variable('End Date')) 

이 ... 그러나 이것은 컴파일 오류가 발생합니다 다음과 같이 정말 할 수 있도록하고 싶습니다 무엇

는 쿼리 변수 주위에 사용 TRUNC는 "일관성 데이터 유형 : 예상 날짜는 번호를 가지고 ". 오라클이 컴파일하기 전에 프롬프트를 숫자 데이터 유형으로 취급하는 이유를 모르겠습니다.

누구든지 @variable 값을 가져 와서 날짜 값을 잘라낼 수있는 것으로 변환 할 수있는 방법을 알고 있습니까?

따라서 저는이 문제를 해결하려고 노력하고 있습니다. 한 가지 염두에 두어야 할 것은 아마도 프롬프트 변수를 가져 와서 TO_DATE를 사용하여 명시 적으로 날짜로 변환 할 수 있다면입니다.

편집 : TRUNC는 효과가 없다고 지적했습니다. "12 : 00:00 AM "은 이미 자정입니다. 그러므로 나는 TRUNC를 잘못 이해했다고 생각한다. 그것이 자정까지 자르는 것처럼 보입니다. 나는 단순히 날짜 부분의 시간 부분을 단순히 제거했다고 생각 했었습니다. 즉, 00:00:00에서 23:59:59 사이에 언제든지 일치가 반환된다는 것을 의미합니다.

내가 원하는 것은 : 예를 들어, SomeDate에 시간대가 11:03 인 경우 End Date 프롬프트에서 해당 날짜 만 지정하면이 날짜가 포함되도록 어떻게해야합니까?

+0

날짜 선택 도구가 항상 시간을 12:00:00 AM으로 전달하면 잘리는 것은 효과가 없습니다. 이미 자정에 있어요. –

+0

@Alex Poole - 흠, 재미 있습니다. 그런 다음 SomeDate 값에 실제로 시간 부분이있는 경우 (예 : 11:02 등) 위의 예제를 간소화했지만 실제로 날짜를보고 싶습니다. 예를 들어, 11:02의 이벤트를 포함하여 오늘 일어나는 모든 이벤트를 나열하려면 "자정"검색을 사용하지 않습니다. 잘라내는 것은 시간 부분이 검색되지 않는다는 것을 의미 할 것이라고 생각했습니다. –

+0

오라클 날짜에는 항상 시간이 있습니다. 제거 할 수 없습니다. 자정으로 설정하십시오. 기본적으로 trunc이 수행하는 것입니다. 따라서 시작일의 00:00:00과 종료일의 23:59:59 사이의 레코드를 일치 시키시겠습니까? –

답변

1

을 당신이 가지고 종료 날짜를 조정할 수 있습니다 끝에서 시작을 00:00:00 23시 59분 59초 사이 SomeDate 값을 일치 시키려면 + 1 당신에게 변수 값 다음날을주고 Oracle date arithmetic를 사용

WHERE 
    A.SomeDate >= @variable('Start') 
AND 
    A.SomeDate < @variable('End Date') + 1 

을하므로 사용자는 포착 경우 : 대신 기본 자정의 시간, 또는 between 대신 범위를 사용 시작일과 종료일에 대해 '01/01/2016 12:00:00 AM'으로 표시되며 2016-01-01 00:00:00 및 2016-01-02 00:00:00으로 각각 평가됩니다. 원하는 경우 interval 구문을 사용할 수 있습니다. 사용하여

덜보다 상한에 대한 당신은 SomeDate이 조정 종료 날짜 2016보다 시작 날짜 2016년 1월 1일 00:00:00 적은-보다 크거나 같은 모든 레코드를 얻을 수 -01-02 00:00:00 - 이는 2016-01-01 23:59:59까지와 동일합니다. (또는 초 단위 정밀도가있는 타임 스탬프 열이있는 경우 최대 23 : 59 : 59.999 ...).

파서가 변수가 문자열입니다 가정하지만 실제로 날짜 인 경우 - 다음 파서 만족 날짜로 캐스팅 할 수 -에 '일치하지 않는 데이터 유형'오류의 원인 :

WHERE 
    A.SomeDate >= CAST(@variable('Start') AS DATE) 
AND 
    A.SomeDate < CAST(@variable('End Date') AS DATE) + 1 

또는 표시된 형식의 문자열로 실제로 전달 된 경우 명시 적으로 변환 할 수 있습니다.

... 올바른 형식인지 확인하십시오. 예를 들어 DD/MM/YYYY 또는 MM/DD/YYYY 일 수 있습니다.

+0

솔루션 소리가 크고 완벽한 의미입니다. 그러나 방금 시도했을 때 컴파일되지 않았습니다. 오류는 "일치하지 않는 데이터 유형 : 예상 날짜가 NUMBER"입니다. 이는 프롬프트 값에 1을 더하는 두 번째 행에 의해 발생합니다. 이제 프롬프트 데이터 유형과 관련된 원래 질문으로 돌아갑니다. 프롬프트를 날짜 값으로 변환해야합니다 ... –

+0

그러면 두 변수 모두에서 여전히 to_date()가 필요할 수 있습니다. 문제는 SQL 구문 분석기가'@variable()'비트를 바인드 변수로보고 문자열로 있다고 가정합니다. 당신은'cast (@variable ('Start') from date)'할 수 있을지도 모르겠지만 문자열로 넘겨지면 형식 마스크를 지정하는 것이 더 낫습니다. - to_date (@variable ('Start') , 'DD/MM/YYYY HH : MI : SS AM') '로 표시됩니다.기본 쿼리는 날짜로 전달되지 않으면 암시 적 변환을 수행하므로 BO가 해당 날짜 형식을 세션 기본값으로 설정할 수 있습니다. –

1

함께 TO_CHAR()TO_DATE()를 사용해보십시오 :

WHERE 
A.SomeDate > TO_DATE(TO_CHAR(@variable('Prompt1'),'ddmmyyyy'),'ddmmyyyy') 
+0

컴파일 할 때 실행될 때 "SQL 실행 중 오류 : ORA-01722 : 잘못된 번호"가 반환됩니다. 예, ddmmyyyy 형식으로 날짜를 입력했습니다. 다른 생각? –

0

먼저 문제는 프롬프트 값의 시간 값이 아니라 SomeDate의 시간 값에서 나옵니다. 그걸 없애면 (자정과 같은 날짜로) 문제가 해결됩니다.

최상의 방법은 유니버스를 수정할 수있는 옵션이있는 경우 다른 개체를 만드는 것입니다. 나는 당신이 이라는 SQL을 가지고있는 SomeDate이라는 객체를 가지고 있다고 가정하고있다. 다른 객체를 만들고, SomeDateOnly으로 정의하고 trunc(a.somedate) * **으로 정의 해 봅시다. WebI에 의해 렌더링 할 때, 생성 할 것이다

trunc(a.somedate) = @variable('Prompt1') 

:

trunc(a.somedate) = '16-08-2016 00:00:00' 
SomeDateOnly 항상 자정 값이 될 것이기 때문에

, 당신은 같은 SQL을 생성 할 것이다, 당신의 메시지와 같음을 사용할 수 있습니다

00:00:00과 8/16/2016 23:59:59에 2011 년 8 월 16 일 사이에 a.somedate이있는 모든 레코드를 반환합니다.

물론, 당신이 날짜 범위를 선택 BETWEEN 사용할 수 있습니다

trunc(a.somedate) between @variable('Start Date') and @variable('End Date') 

당신이 우주에 대한 액세스 권한이없는 경우에도 WebI의 생성 된 SQL을 수정하여 위의 구문을 사용할 수 있습니다. (나는 당신이하고 있었던 것이 어쨌든 가정하고있다).

당신을 위해 위의 작품, 다음은 관련이 있지만, 어쨌든 그것을 해결하기 위해 원하는 경우

는 수신 된 "잘못된 번호"오류의 원인 때문에 WebI가 날짜를 포맷하는 방식입니다 SQL.

A.SomeDate = TRUNC(@variable('Prompt1')) 

다음 WebI가 날짜 문자열와 @variable (...)를 교체하고 오라클로 전송하기 전에 다음과 같이 렌더링됩니다 :

당신은 당신의 쿼리 문자열이있는 경우
A.SomeDate = TRUNC('16-08-2016 00:00:00') 

물론 이것은 실제로 날짜 값이라는 것을 말할 것도 없으므로 TRUNC() 함수에는 의미가 없습니다.

to_date 프롬프트가 먼저 표시되지만 정확한 날짜 형식을 사용해야합니다. WebI는 기본이 아닌 형식으로 각 세션에 대한 NLS_DATE_FORMAT을 설정, 그래서 당신은 사용해야 할 것입니다 :

A.SomeDate = TRUNC(to_date(@variable('Prompt1')),'dd-mm-yyyy hh24:mi:ss') 

을하지만 somedate하지 프롬프트 응답 값을 TRUNC 할 필요가 있기 때문에 다시, 이것은 무관하다.


* 더 나은 여전히, SomeDateTimeSomeDate의 이름을 변경하고, 새 개체 SomeDate

이름을 **이 꽤 일반적이다 - 같은 소스 필드에 여러 개체를 가지고. 때로는 특정 트랜잭션을 나열하기 위해 날짜/시간 값을 원하지만 가끔 날짜 만 필요합니다 (트랜잭션을 날짜별로 계산하기 위해). 따라서 두 가지를 모두 사용하는 것이 매우 유용합니다.