[SQL] 어떻게 DO 블록에서 선택 쿼리를 수행하기 위해?
SQL어떻게 DO 블록에서 선택 쿼리를 수행하기 위해?
나는 포트에 PostgreSQL을에 MS SQL-Server에서 SQL 아래 코드를 원한다.
DECLARE @iStartYear integer
DECLARE @iStartMonth integer
DECLARE @iEndYear integer
DECLARE @iEndMonth integer
SET @iStartYear = 2012
SET @iStartMonth = 4
SET @iEndYear = 2016
SET @iEndMonth = 1
;WITH CTE
AS
(
SELECT
--@iStartYear AS TheStartYear
@iStartMonth AS TheRunningMonth
,@iStartYear AS TheYear
,@iStartMonth AS TheMonth
UNION ALL
SELECT
--CTE.TheStartYear AS TheStartYear
--@iStartYear AS TheStartYear
CTE.TheRunningMonth + 1 AS TheRunningMonth
--,CTE.TheStartYear + (CTE.TheRunningMonth / 12) AS TheYear
,@iStartYear + (CTE.TheRunningMonth / 12) AS TheYear
,(CTE.TheMonth + 1 -1) % 12 + 1 AS TheMonth
FROM CTE
WHERE (1=1)
AND
(
CASE
--WHEN (CTE.TheStartYear + (CTE.TheRunningMonth / 12) ) < @iEndYear
WHEN (@iStartYear + (CTE.TheRunningMonth / 12) ) < @iEndYear
THEN 1
--WHEN (CTE.TheStartYear + (CTE.TheRunningMonth / 12) ) = @iEndYear
WHEN (@iStartYear + (CTE.TheRunningMonth / 12) ) = @iEndYear
THEN
CASE
WHEN ( (CTE.TheMonth + 1 -1) % 12 + 1 ) <= @iEndMonth
THEN 1
ELSE 0
END
ELSE 0
END = 1
)
)
SELECT * FROM CTE
이것은 내가 지금까지있는 것입니다.
DO $$
DECLARE r record;
DECLARE i integer;
DECLARE __iStartYear integer;
DECLARE __iStartMonth integer;
DECLARE __iEndYear integer;
DECLARE __iEndMonth integer;
DECLARE __mytext character varying(200);
BEGIN
i:= 5;
--RAISE NOTICE 'test'
--RAISE NOTICE 'test1' || 'test2';
__mytext := 'Test message';
--RAISE NOTICE __mytext;
RAISE NOTICE '%', __mytext;
RAISE NOTICE '% %', 'arg1', 'arg2';
--SQL Standard: "CAST( value AS text )" [or varchar]
--PostgreSQL short-hand: "value::text"
__mytext := 'Test ' || i::text;
RAISE NOTICE '%', __mytext;
__mytext := 'mynumber: ' || CAST(i as varchar(33)) || '%';
RAISE NOTICE '%', __mytext;
__iStartYear := 2012;
__iStartMonth := 4;
__iEndYear := 2016;
__iEndMonth := 1;
--PERFORM 'abc';
SELECT 'abc';
-- SELECT __iStartMonth AS TheRunningMonth;
-- RAISE NOTICE 'The raise_test() function began.' + CAST( i AS text ) ;
-- FOR r IN SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'VIEW' AND table_schema = 'public'
-- LOOP
-- EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
--END LOOP;
END$$;
당신이 볼 수 있듯이 인상 통지 기능을 갖춘 '인쇄'에 원하는 때, 나는 몇 가지 문제가 있었다. 하지만 구글이를 해결하기 위해 관리.
이전의 경험에서, 나는 유일한 진짜 문제는 내가이 필요한 블록을 할 수있는 몇 가지 변수를 정의해야한다는 것입니다, 그래서에만 CTE 전에 재귀를 추가해야 CTE의와 포스트 그레스 구문은 매우 유사 나는 것을 알 수 있습니다.
이 간단한 질문 결과에서 나는 가지고 : 어떻게 DO 블록에서 선택 쿼리를 "수행"할 수 있습니까? 나는 pgAdmin3의 '데이터 출력'탭에서 결과를보고 싶어요. 그리고 함수를 작성하고 싶지 않아요.
해결법
-
==============================
1.할 일 명령 행을 반환하지 않습니다. 당신은 공지 사항 또는 (언어 plpgsql와) RAISE 다른 메시지를 보낼 수 있습니다 또는 당신은 (임시) 테이블을 작성하고 나중에이 문제를 해결하기 위해 그것에서 선택할 수 있습니다.
할 일 명령 행을 반환하지 않습니다. 당신은 공지 사항 또는 (언어 plpgsql와) RAISE 다른 메시지를 보낼 수 있습니다 또는 당신은 (임시) 테이블을 작성하고 나중에이 문제를 해결하기 위해 그것에서 선택할 수 있습니다.
다양한 방법으로 함수의 RETURNS 절 또는 OUT / INOUT 매개 변수와 반환과 반환 유형을 정의 할 수있는하지만 실제로는, 대신 (plpgsql) 함수를 만듭니다.
당신이 기능을 저장하고 다른 연결 볼 수 원하지 않는 경우, 문서화되지 않은 있지만 잘 확립 된 기능이다 "일시적"기능을 고려 :
손에서 문제를 들어 당신이 중 하나를 필요로하지 않는 것. 대신이 간단한 쿼리를 사용합니다 :
SELECT row_number() OVER () AS running_month , extract('year' FROM m) AS year , extract('month' FROM m) AS month FROM generate_series(timestamp '2012-04-01' , timestamp '2016-01-01' , interval '1 month') m;
DB <> 바이올린 여기
왜?
-
==============================
2.여기에 질문이 더 맞도록되어 있기 때문에, 질문에 진짜 대답해야 어윈이 조언하는 임시 테이블과 해결 방법에 대한 자세한 내용은 "개발 과정에서, 어떻게 빨리 선택과 코드 블록을 작성하고 결과를 볼 수 있습니다 "(하우투 빠르게"테이블 반환 함수 디버깅 / 핵 물질이이 실제 쿼리를 해결하는 것보다 처음부터 근본적인 질문을했다 "). 나는 내가 generate_series 부분 100 번 upvote에하고 싶은 말을해야하지만) 그것은 임시 테이블에 결과를 선택하는 것이 가능하다, 그리고, DO 블록 외부에서 임시 테이블에서 선택 이 같은 :
여기에 질문이 더 맞도록되어 있기 때문에, 질문에 진짜 대답해야 어윈이 조언하는 임시 테이블과 해결 방법에 대한 자세한 내용은 "개발 과정에서, 어떻게 빨리 선택과 코드 블록을 작성하고 결과를 볼 수 있습니다 "(하우투 빠르게"테이블 반환 함수 디버깅 / 핵 물질이이 실제 쿼리를 해결하는 것보다 처음부터 근본적인 질문을했다 "). 나는 내가 generate_series 부분 100 번 upvote에하고 싶은 말을해야하지만) 그것은 임시 테이블에 결과를 선택하는 것이 가능하다, 그리고, DO 블록 외부에서 임시 테이블에서 선택 이 같은 :
DO $$ DECLARE r record; DECLARE i integer; DECLARE __iStartYear integer; DECLARE __iStartMonth integer; DECLARE __iEndYear integer; DECLARE __iEndMonth integer; DECLARE __mytext character varying(200); BEGIN i:= 5; -- Using Raise: -- http://www.java2s.com/Code/PostgreSQL/Postgre-SQL/UsingRAISENOTICE.htm --RAISE NOTICE 'test' --RAISE NOTICE 'test1' || 'test2'; __mytext := 'Test message'; --RAISE NOTICE __mytext; RAISE NOTICE '%', __mytext; RAISE NOTICE '%', 'arg1' || 'arg2'; RAISE NOTICE '% %', 'arg1', 'arg2'; --SQL Standard: "CAST( value AS text )" [or varchar] --PostgreSQL short-hand: "value::text" __mytext := 'Test ' || i::text; RAISE NOTICE '%', __mytext; __mytext := 'mynumber: ' || CAST(i as varchar(33)) || '%'; RAISE NOTICE '%', __mytext; __iStartYear := 2012; __iStartMonth := 4; __iEndYear := 2016; __iEndMonth := 1; --PERFORM 'abc'; --CREATE TEMP TABLE mytable AS SELECT * FROM orig_table; --DROP TABLE table_name CASCADE; --DROP TABLE IF EXISTS table_name CASCADE; --DROP TABLE IF EXISTS tbl; --CREATE TEMP TABLE tbl AS SELECT 1 as a,2 as b,3 as c; DROP TABLE IF EXISTS mytable; CREATE TEMP TABLE mytable AS WITH RECURSIVE CTE AS ( SELECT --__iStartYear AS TheStartYear __iStartMonth AS TheRunningMonth ,__iStartYear AS TheYear ,__iStartMonth AS TheMonth UNION ALL SELECT --CTE.TheStartYear AS TheStartYear --__iStartYear AS TheStartYear CTE.TheRunningMonth + 1 AS TheRunningMonth --,CTE.TheStartYear + (CTE.TheRunningMonth / 12) AS TheYear ,__iStartYear + (CTE.TheRunningMonth / 12) AS TheYear ,(CTE.TheMonth + 1 -1) % 12 + 1 AS TheMonth FROM CTE WHERE (1=1) AND ( CASE --WHEN (CTE.TheStartYear + (CTE.TheRunningMonth / 12) ) < __iEndYear WHEN (__iStartYear + (CTE.TheRunningMonth / 12) ) < __iEndYear THEN 1 --WHEN (CTE.TheStartYear + (CTE.TheRunningMonth / 12) ) = __iEndYear WHEN (__iStartYear + (CTE.TheRunningMonth / 12) ) = __iEndYear THEN CASE WHEN ( (CTE.TheMonth + 1 -1) % 12 + 1 ) <= __iEndMonth THEN 1 ELSE 0 END ELSE 0 END = 1 ) ) SELECT * FROM CTE; -- SELECT __iStartMonth AS TheRunningMonth; --RAISE NOTICE 'The raise_test() function began.' + CAST( i AS text ) ; --FOR r IN SELECT table_schema, table_name FROM information_schema.tables WHERE table_type = 'VIEW' AND table_schema = 'public' --LOOP -- EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser'; --END LOOP; END$$; SELECT * FROM mytable;
어떤 정말 빨리 BTW 다음과 같습니다 테이블 반환 기능 버전으로 쿼리를 설정하는 기본입니다 :
-- SELECT * FROM tfu_V_RPT_MonthList(2012,1,2013,4); CREATE OR REPLACE FUNCTION tfu_V_RPT_MonthList ( __iStartYear integer ,__iStartMonth integer ,__iEndYear integer ,__iEndMonth integer ) RETURNS TABLE( TheRunningMonth integer ,TheYear integer ,TheMonth integer ) AS $BODY$ DECLARE -- Declare vars here BEGIN RETURN QUERY WITH RECURSIVE CTE AS ( SELECT --__iStartYear AS TheStartYear __iStartMonth AS TheRunningMonth ,__iStartYear AS TheYear ,__iStartMonth AS TheMonth UNION ALL SELECT --CTE.TheStartYear AS TheStartYear --__iStartYear AS TheStartYear CTE.TheRunningMonth + 1 AS TheRunningMonth --,CTE.TheStartYear + (CTE.TheRunningMonth / 12) AS TheYear ,__iStartYear + (CTE.TheRunningMonth / 12) AS TheYear ,(CTE.TheMonth + 1 -1) % 12 + 1 AS TheMonth FROM CTE WHERE (1=1) AND ( CASE --WHEN (CTE.TheStartYear + (CTE.TheRunningMonth / 12) ) < __iEndYear WHEN (__iStartYear + (CTE.TheRunningMonth / 12) ) < __iEndYear THEN 1 --WHEN (CTE.TheStartYear + (CTE.TheRunningMonth / 12) ) = __iEndYear WHEN (__iStartYear + (CTE.TheRunningMonth / 12) ) = __iEndYear THEN CASE WHEN ( (CTE.TheMonth + 1 -1) % 12 + 1 ) <= __iEndMonth THEN 1 ELSE 0 END ELSE 0 END = 1 ) ) SELECT * FROM CTE ; END; $BODY$ LANGUAGE plpgsql VOLATILE --ALTER FUNCTION dbo.tfu_v_dms_desktop(character varying) OWNER TO postgres;
BTW,이를 달성하기 위해 부풀게는 SQL-Server 코드를 보라 :
SELECT extract('year' FROM m) AS RPT_Year -- http://www.postgresql.org/docs/current/interactive/functions-formatting.html#FUNCTIONS-FORMATTING-DATETIME-TABLE --,to_char(m, 'TMmon') --,to_char(m, 'TMmonth') ,to_char(m, 'Month') AS RPT_MonthName ,m AS RPT_MonthStartDate ,m + INTERVAL '1 month' - INTERVAL '1 day' AS RPT_MonthEndDate FROM ( SELECT generate_series((2012::text || '-' || 4::text || '-01')::date, (2016::text || '-' || 1::text || '-01')::date, interval '1 month') AS m ) AS g ;
이로 바뀝니다 :
DECLARE @in_iStartYear integer DECLARE @in_iStartMonth integer DECLARE @in_iEndYear integer DECLARE @in_iEndMonth integer SET @in_iStartYear = 2012 SET @in_iStartMonth = 12 SET @in_iEndYear = 2016 SET @in_iEndMonth = 12 DECLARE @strOriginalLanguage AS nvarchar(200) DECLARE @dtStartDate AS datetime DECLARE @dtEndDate AS datetime SET @strOriginalLanguage = (SELECT @@LANGUAGE) SET @dtStartDate = DATEADD(YEAR, @in_iStartYear - 1900, 0) SET @dtStartDate = DATEADD(MONTH, @in_iStartMonth -1, @dtStartDate) SET @dtEndDate = DATEADD(YEAR, @in_iEndYear - 1900, 0) SET @dtEndDate = DATEADD(MONTH, @in_iEndMonth -1, @dtEndDate) SET LANGUAGE 'us_english' ;WITH CTE_YearsMonthStartAndEnd AS ( SELECT YEAR(@dtStartDate) AS RPT_Year ,DATENAME(MONTH, @dtStartDate) AS RPT_MonthName ,@dtStartDate AS RPT_MonthStartDate ,DATEADD(DAY, -1, DATEADD(MONTH, 1, @dtStartDate)) AS RPT_MonthEndDate UNION ALL SELECT YEAR(DATEADD(MONTH, 1, CTE_YearsMonthStartAndEnd.RPT_MonthStartDate)) AS RPT_Year ,DATENAME(MONTH, DATEADD(MONTH, 1, CTE_YearsMonthStartAndEnd.RPT_MonthStartDate)) AS RPT_MonthName ,DATEADD(MONTH, 1, CTE_YearsMonthStartAndEnd.RPT_MonthStartDate) AS RPT_MonthStartDate ,DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(MONTH, 1, CTE_YearsMonthStartAndEnd.RPT_MonthStartDate)) ) AS RPT_MonthEndDate FROM CTE_YearsMonthStartAndEnd WHERE DATEADD(MONTH, 1, CTE_YearsMonthStartAndEnd.RPT_MonthStartDate) <= @dtEndDate ) SELECT RPT_Year ,RPT_MonthName ,RPT_MonthStartDate ,RPT_MonthEndDate FROM CTE_YearsMonthStartAndEnd
(감사 어윈!))
-
==============================
3.이것은 너무 오프 주제 (IMHO)이며, 도움이 될 수 있습니다 ...
이것은 너무 오프 주제 (IMHO)이며, 도움이 될 수 있습니다 ...
나는이 트랜잭션의 문들을 실행하고 (기록이 영향을 사용자 지정 오류 코드) 트랜잭션이 처리 된 방법 PHP 스크립트에 나타냅니다 일부 (아주 작은) 데이터를 반환하는 데 필요한 곳에 나는 최근에이 문제를 다 퉜다.
인상주의 사항 및 RAISE [예외] 패러다임에 집착, 나는 그것이 최고의 반환되는주의 사항 / 예외 JSON 문자열을 반환 발견했다. 이 방법은 PHP 응용 프로그램이해야 할 것입니다 모두 사용 pg_last_notice () 또는 얻고 JSON 문자열을 디코딩하는 pg_last_error ()입니다.
EG
RAISE EXCEPTION '{"std_response":{"affected":%,"error":%}}', var_affected, var_error_id;
또는
RAISE NOTICE '{"std_response":{"affected":%,"error":%}}', var_affected, var_error_id;
"std_response"라는 이름의 반환 JSON 객체가 실제로 스크립트의 모든 유형에 대한 표준 응답이기 때문에 하중이 래퍼 기능 때문에 쓰기 단위 테스트에 정말 쉽습니다을하게하고, SQL은 항상 할 수있는 "std_response"개체를 반환합니다 실행 그것의 값을 테스트했습니다.
당신이 RAISE 메시지의 데이터 TINY 조각을 반환하는 경우 (-하지 않도록 한계가 무엇인지 내가 96,000 자까지 본 적이 있지만이 방법을 반환)이 패러다임에만 사용되어야한다. 당신이 큰 데이터 집합을 반환해야 할 경우, 당신은 테이블에 결과 집합을 저장하지만 적어도 당신은 여전히 호출 된 SQL 속해 정확히 어떤 기록을 분리하는이 패러다임을 사용할 수 있어야합니다. 즉 UUID와 함께 테이블에 데이터를 배치 등등과 같은 공지의 UUID를 반환 :
RAISE NOTICE '{"table_name":{"affected":%,"uuid":%}}', var_affected, var_uuid;
이것에 대해 좋은 점은 여전히 구조화 된 데이터를 선택 할 테이블 설명이기 때문에, 그것은 또한 응용 프로그램에서 단위 테스트와 함께 사용할 수 있다는 것입니다.
(또는, 당신은 또한 그 방법은 당신이 I / O를 바로 저장하는 응용 프로그램을 결과를-디스크 세트를 처리하지 않아도, memcache에에 결과 세트를 저장하고 응용 프로그램 픽업에게 거기에서 데이터 집합을 가지고 PostgreSQL을 사용할 수 있습니다 ) 바로 다음 몇 가지 HTML을 생성 할 때 스크립트 완료를 버려야하는 데 사용할
-
==============================
4.다음과 같은 방법을 사용할 수있는 DO 익명 코드 블록에서 레코드를 얻으려면 :
다음과 같은 방법을 사용할 수있는 DO 익명 코드 블록에서 레코드를 얻으려면 :
DO $$ DECLARE _query text; _cursor CONSTANT refcursor := '_cursor'; BEGIN _query := 'SELECT * FROM table_name'; OPEN _cursor FOR EXECUTE _query; END $$; FETCH ALL FROM _cursor;
주의
더에 대한 커서. 기술 소스 여기 (러시아어).
from https://stackoverflow.com/questions/14652477/how-to-perform-a-select-query-in-a-do-block by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 인서트 문자열은 사용자 생성 된 변수에있을 때 SQL 삽입에 대한 작은 따옴표를 ... 탈출하는 방법 (0) | 2020.07.05 |
---|---|
[SQL] C #의 WinForm에서의 app.config를 사용하여 데이터베이스 연결 문자열에 액세스 (0) | 2020.07.05 |
[SQL] ISNULL NULL의 대 (0) | 2020.07.05 |
[SQL] SSRS 표현에 '처럼'사용 (0) | 2020.07.05 |
[SQL] WHERE IN 절에서 SQL 사용 CASE 문 (0) | 2020.07.05 |