programing

저장 프로시저를 사용하지 않고 n번 반복 실행

starjava 2023. 10. 9. 21:16
반응형

저장 프로시저를 사용하지 않고 n번 반복 실행

저장 프로시저를 사용하지 않고 MySql에서 n번 실행되는 루프를 작성하려면 어떻게 해야 합니까?

저장 프로시저를 사용하는 방법은 다음과 같습니다.

DELIMITER $$
DROP PROCEDURE IF EXISTS test$$
CREATE PROCEDURE test()
BEGIN
   DECLARE count INT DEFAULT 0;
   WHILE count < 10 DO
      /**Sql statement**/
      SET count = count + 1;
   END WHILE;
END$$
DELIMITER ;  

그런 다음 절차를 이렇게 실행합니다.

call test();  

저장 프로시저를 제거하고 일반 쿼리를 실행하면 다음 오류와 함께 실패합니다.

1064 - SQL 구문에 오류가 있습니다. MySQL 서버 버전에 해당하는 매뉴얼에서 'DECLARE count INT DEFAULT 0; BITHINE Count < 10 Do at line' 2에 가까운 구문을 사용할 수 있습니다.

나는 인터넷을 통해 운이 따르지 않는 해결책을 찾아 보았습니다.

주석 기반 편집:

위에 저장된 프로시저는 제가 원하는 대로 수행합니다.그것은 10번 루프하고 내 sql 문을 실행합니다.이제는 저장된 절차를 사용하지 않고 같은 일을 해내고 싶습니다.다음과 같은 경우:

DECLARE count INT DEFAULT 0;
   WHILE count < 10 DO
      /**Sql statement**/
      SET count = count + 1;
   END WHILE;  

Flow Control Statement에 대한 MySQL 문서에는 다음과 같이 나와 있습니다.

MySQL은 저장된 프로그램 내의 흐름 제어를 위해 IF, CASE, 반복, Leave LOOP, WHITE 및 REEPITE 구성을 지원합니다.

저장된 프로그램보기에 대한 문서는 다음과 같습니다.

저장된 프로그램 정의에는 복합 문, 루프, 조건 선언된 변수를 사용할 수 있는 본문이 포함됩니다.

복합문 구문

이 절에서는 BEGIN...에 대한 구문을 설명합니다.END 컴파운드 문 및 저장된 프로그램 본문에서 사용할 수 있는 기타 문:저장 프로시저 및 함수, 트리거 및 이벤트.

복합 문은 다른 블록, 변수, 조건 처리기 및 커서에 대한 선언, 루프 및 조건 테스트와 같은 흐름 제어 구성을 포함할 수 있는 블록입니다.

따라서 저장된 프로시저, 함수 또는 트리거 내에서만 명시적 루프를 실행할 수 있습니다.


SQL 문에서 수행하는 작업에 따라 숫자 테이블(또는 보기)을 사용할 수 있습니다(mysql, MYSQL: Sequential Number Table).

쿼리가 다음과 같은 경우SELECT그리고 당신의 결과를 돌려주는 것은 괜찮습니다.SELECT(10개의 개별 결과 집합이 아닌) 긴 결과 집합을 10번 사용하면 다음과 같은 작업을 수행할 수 있습니다.

SELECT MainQuery.*
FROM
    (
        SELECT 1 AS Number 
        UNION ALL SELECT 2
        UNION ALL SELECT 3
        UNION ALL SELECT 4
        UNION ALL SELECT 5
        UNION ALL SELECT 6
        UNION ALL SELECT 7
        UNION ALL SELECT 8
        UNION ALL SELECT 9
        UNION ALL SELECT 10
    ) AS Numbers
    CROSS JOIN
    (
        SELECT 'some data' AS Result
    ) AS MainQuery

INSERT 예제

데이터베이스에 영구적인 숫자표를 두는 것을 추천합니다.그것은 많은 경우에 유용합니다.위의 링크에서 생성 방법을 참조하십시오.

그래서, 당신이 자리가 있다면.Numbers와 함께intNumber예를 들어, 1에서 100K 사이의 값을 사용하고 이 열에 기본 키를 설정하면 이 루프 대신 다음과 같습니다.

DECLARE count INT DEFAULT 0;
WHILE count < 10 DO
    INSERT INTO table_name(col1,col2,col3) 
    VALUES("val1","val2",count);

    SET count = count + 1;
END WHILE;

다음과 같이 쓸 수 있습니다.

INSERT INTO table_name(col1,col2,col3)
SELECT ("val1", "val2", Numbers.Number-1)
FROM Numbers
WHERE Numbers.Number <= 10;

이것은 또한 거의 10배나 빠르게 작동할 것입니다.

MariaDB Sequence Engine으로 직접 할 수 있습니다.MariaDB는 MySQL을 이진법으로 대체한 것입니다.

"시퀀스 엔진을 사용하면 시작 값, 끝 값 및 증분이 지정된 숫자(양의 정수)의 오름차순 또는 내림차순을 만들 수 있습니다."

[수동 시퀀스 엔진]

다음은 몇 가지 샘플입니다.

    mysql -uroot -p
    Enter password: xxxxxxx
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 5
    Server version: 10.0.20-MariaDB-log Homebrew

    Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

    MariaDB [(none)]> use tmp
    Database changed
    MariaDB [tmp]> select version();
    +---------------------+
    | version()           |
    +---------------------+
    | 10.0.20-MariaDB-log |
    +---------------------+
    1 row in set (0.00 sec)

    MariaDB [tmp]> select * from seq_1_to_10;
    +-----+
    | seq |
    +-----+
    |   1 |
    |   2 |
    |   3 |
    |   4 |
    |   5 |
    |   6 |
    |   7 |
    |   8 |
    |   9 |
    |  10 |
    +-----+
    10 rows in set (0.00 sec)

    MariaDB [tmp]> select * from seq_1_to_10_step_2;
    +-----+
    | seq |
    +-----+
    |   1 |
    |   3 |
    |   5 |
    |   7 |
    |   9 |
    +-----+
    5 rows in set (0.00 sec)

MariaDB [tmp]> SELECT DAYNAME('1980-12-05' + INTERVAL (seq) YEAR) day,
    ->     '1980-12-05' + INTERVAL (seq) YEAR date FROM seq_0_to_40;
+-----------+------------+
| day       | date       |
+-----------+------------+
| Friday    | 1980-12-05 |
| Saturday  | 1981-12-05 |
| Sunday    | 1982-12-05 |
| Monday    | 1983-12-05 |
| Wednesday | 1984-12-05 |
| Thursday  | 1985-12-05 |
| Friday    | 1986-12-05 |
| Saturday  | 1987-12-05 |
| Monday    | 1988-12-05 |
| Tuesday   | 1989-12-05 |
| Wednesday | 1990-12-05 |
| Thursday  | 1991-12-05 |
| Saturday  | 1992-12-05 |
| Sunday    | 1993-12-05 |
| Monday    | 1994-12-05 |
| Tuesday   | 1995-12-05 |
| Thursday  | 1996-12-05 |
| Friday    | 1997-12-05 |
| Saturday  | 1998-12-05 |
| Sunday    | 1999-12-05 |
| Tuesday   | 2000-12-05 |
| Wednesday | 2001-12-05 |
| Thursday  | 2002-12-05 |
| Friday    | 2003-12-05 |
| Sunday    | 2004-12-05 |
| Monday    | 2005-12-05 |
| Tuesday   | 2006-12-05 |
| Wednesday | 2007-12-05 |
| Friday    | 2008-12-05 |
| Saturday  | 2009-12-05 |
| Sunday    | 2010-12-05 |
| Monday    | 2011-12-05 |
| Wednesday | 2012-12-05 |
| Thursday  | 2013-12-05 |
| Friday    | 2014-12-05 |
| Saturday  | 2015-12-05 |
| Monday    | 2016-12-05 |
| Tuesday   | 2017-12-05 |
| Wednesday | 2018-12-05 |
| Thursday  | 2019-12-05 |
| Saturday  | 2020-12-05 |
+-----------+------------+
41 rows in set (0.00 sec)

MariaDB [tmp]>

여기 하나의 샘플:

MariaDB [(none)]> use tmp
Database changed
MariaDB [tmp]> SELECT * FROM seq_1_to_5,
    -> (SELECT * FROM animals) AS x
    -> ORDER BY seq;
+-----+------+-----------+-----------------+
| seq | id   | name      | specie          |
+-----+------+-----------+-----------------+
|   1 |    1 | dougie    | dog-poodle      |
|   1 |    6 | tweety    | bird-canary     |
|   1 |    5 | spotty    | turtle-spotted  |
|   1 |    4 | mr.turtle | turtle-snapping |
|   1 |    3 | cadi      | cat-persian     |
|   1 |    2 | bonzo     | dog-pitbull     |
|   2 |    4 | mr.turtle | turtle-snapping |
|   2 |    3 | cadi      | cat-persian     |
|   2 |    2 | bonzo     | dog-pitbull     |
|   2 |    1 | dougie    | dog-poodle      |
|   2 |    6 | tweety    | bird-canary     |
|   2 |    5 | spotty    | turtle-spotted  |
|   3 |    6 | tweety    | bird-canary     |
|   3 |    5 | spotty    | turtle-spotted  |
|   3 |    4 | mr.turtle | turtle-snapping |
|   3 |    3 | cadi      | cat-persian     |
|   3 |    2 | bonzo     | dog-pitbull     |
|   3 |    1 | dougie    | dog-poodle      |
|   4 |    2 | bonzo     | dog-pitbull     |
|   4 |    1 | dougie    | dog-poodle      |
|   4 |    6 | tweety    | bird-canary     |
|   4 |    5 | spotty    | turtle-spotted  |
|   4 |    4 | mr.turtle | turtle-snapping |
|   4 |    3 | cadi      | cat-persian     |
|   5 |    5 | spotty    | turtle-spotted  |
|   5 |    4 | mr.turtle | turtle-snapping |
|   5 |    3 | cadi      | cat-persian     |
|   5 |    2 | bonzo     | dog-pitbull     |
|   5 |    1 | dougie    | dog-poodle      |
|   5 |    6 | tweety    | bird-canary     |
+-----+------+-----------+-----------------+
30 rows in set (0.00 sec)

MariaDB [tmp]>

그건 불가능합니다.

MySQL 문서를 다 읽었는데 문장은 기능/절차 본문에서만 선언할 수 있습니다.

Berd가 언급한 것처럼 순차적으로 내장된 것으로 할 수는 있지만 조금 이상합니다.

SET @i = 1;
set @str = 'a,b,c,d,e,f,g,h';

select temp.length into @length from 
(select
        ROUND(   
            (
                LENGTH(dt.data)
                - LENGTH( REPLACE (dt.data, ",", "") ) 
            ) / LENGTH(",")        
        )+1 AS length   
     from (select @str as data) dt
 ) temp;

SET @query = CONCAT('select substring_index(
    substring_index(@str, '','', seq), 
    '','', 
    -1
  ) as letter from seq_', @i, '_to_',@length);

PREPARE q FROM @query;
EXECUTE q;
DECLARE @count INT = 0;

   WHILE @count < 10 
    BEGIN
     DELETE TOP (300)
     FROM EmployeeInformation
     WHERE IsSynced=1 and CreatedDate<'2020-02-29'
     SET @count = @count + 1;
   END

이 코드는 저한테 효과가 있어요.

언급URL : https://stackoverflow.com/questions/32367957/loop-n-times-without-using-a-stored-procedure

반응형