- 投稿日:2022-04-02T23:27:47+09:00
Python を使用して Azure Database for MySQL に接続して 自動生成データを書き込みしてみました
概要 この記事 の応用編です。 指定した件数・間隔でデータを自動生成し、MySQLサーバのデータベースに書き込む Python プログラムです。テーブルの初期化、データの読み込み、データの削除も可能となっています。 ローカル環境 macOS Monterey 12.3 python 3.8.12 Azure CLI 2.34.1 mysql Ver 8.0.28 for macos12.2 on x86_64 (Homebrew) 前提条件 Azure環境がすでに用意されていること(テナント/サブスクリプション) ローカル環境に「azure cli」がインストールされていること ローカル環境に「mysql」がインストールされていること 事前準備 この記事 を実行し、Azure Database for MySQL を Single構成 で作成できていること 項目 値 MySQLサーバ名 iturumysql01.mysql.database.azure.com データベース名 iotdummydb 管理者名 adminadmin@iturumysql01 管理者パスワード HogeHogeHoge! PythonプログラムからのMySQLサーバへのDB操作 Pythonプログラム 作成するテーブル名:inventory mysql_IoTdummy.py import mysql.connector from mysql.connector import errorcode import time from datetime import date, datetime import random import json import argparse import string from faker.factory import Factory import pandas as pd import numpy as np from tqdm import tqdm # ダミーデータ作成のための Faker の使用 Faker = Factory.create fake = Faker() fake = Faker("ja_JP") # ダミーセクション?(大文字アルファベットを定義) section = string.ascii_uppercase # MySQLサーバ接続設定情報 config = { 'host': 'iturumysql01.mysql.database.azure.com', 'user': 'adminadmin@iturumysql01', 'password': 'HogeHogeHoge!', 'database': 'iotdummydb' } # ダミーデータの作成 def iot_json_data(count, proc): iot_items = json.dumps({ 'items': [{ 'iot_id': i, # IoT id 'proc': proc, # データ生成プロセス名 'section': random.choice(section), # IoT機器セクション 'iot_num': fake.zipcode(), # IoT機器番号 'iot_state': fake.prefecture(), # IoT設置場所 'val_1': random.uniform(100, 200), # IoT値−1 'val_2': random.uniform(50, 90), # IoT値−2 'created_at': generate_time() # データ生成時間 } for i in range(count) ] }, ensure_ascii=False).encode('utf-8') return iot_items # ダミーデータの生成時間 def generate_time(): dt_time = datetime.now() gtime = json_trans_date(dt_time) return gtime # date, datetimeの変換関数 def json_trans_date(obj): # 日付型を文字列に変換 if isinstance(obj, (datetime, date)): return obj.isoformat() # 上記以外は対象外. raise TypeError ("Type %s not serializable" % type(obj)) # MySQLサーバ接続 def ConnectionToMySQL(): try: conn = mysql.connector.connect(**config) print("\nConnection established\n") except mysql.connector.Error as err: if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: return 0, "Something is wrong with the user name or password" elif err.errno == errorcode.ER_BAD_DB_ERROR: return 0, "Database does not exist" else: return 0, err else: cursor = conn.cursor() return 1, conn # メイン : ターミナル出力用 def tm_main(count, proc, wait): print('ターミナル 出力\n') # ダミーデータ生成 iotjsondata = iot_json_data(count, proc) json_dict = json.loads(iotjsondata) # ターミナル出力 for item in json_dict['items']: print(item) time.sleep(wait) # メイン : Show Database def show_db_main(): print('MySqlサーバへの接続確認') code, conn = ConnectionToMySQL() if code == 0 : print(conn) else : print(conn) conn.close() # メイン : Init Database def init_db_main(): print('データベース・テーブルの新規作成') # DBへの接続 code, conn = ConnectionToMySQL() if code == 0 : print(conn) return else : cursor = conn.cursor() # Drop previous table of same name if one exists cursor.execute("DROP TABLE IF EXISTS inventory;") print("\tFinished dropping table (if existed).") # Create table cursor.execute("\ CREATE TABLE inventory (\ id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \ iot_id int NOT NULL, \ proc VARCHAR(10) NOT NULL, \ section VARCHAR(2) NOT NULL, \ iot_num VARCHAR(10) NOT NULL, \ iot_state VARCHAR(10) NOT NULL, \ val_1 float NOT NULL, \ val_2 float NOT NULL, \ created_at datetime DEFAULT NULL, \ updated_at datetime DEFAULT NULL \ );"\ ) print("\tFinished creating table.\n") # 作成したテーブル情報の取得 cursor.execute("show columns from inventory;") rows = cursor.fetchall() # 多次元リストを Pandas DataFrame を利用して表示する df = pd.DataFrame(rows, columns = ['Field','Type','Null','Key','Default','Extra']) print(df) # Cleanup cursor.close() conn.close() print("Done.") # メイン : Write Database def write_db_main(count, proc, wait): print('データベース・テーブルへのデータ書き込み') # DBへの接続 code, conn = ConnectionToMySQL() if code == 0 : print(conn) return else : cursor = conn.cursor() # ダミーデータ生成 iotjsondata = iot_json_data(count, proc) json_dict = json.loads(iotjsondata) # インサート項目の定義 insert_sql = "INSERT INTO inventory \ (iot_id, proc, section, iot_num, iot_state, val_1, val_2, created_at) \ values (%s,%s,%s,%s,%s,%s,%s,%s);" # プログレスバーで進捗状況を表示 for item in tqdm(json_dict['items']): # データのインサート # print(list(item.values())) cursor.execute(insert_sql, list(item.values())) conn.commit() time.sleep(wait) # Cleanup cursor.close() conn.close() print("Inserted",count,"row(s) of data.") print("Done.") # メイン : Read Database def read_db_main(): print('データベース・テーブルへのデータ読み込み') # DBへの接続 code, conn = ConnectionToMySQL() if code == 0 : print(conn) return else : cursor = conn.cursor() # Read table data cursor.execute("SELECT * FROM inventory;") rows = cursor.fetchall() print(f'Read: {cursor.rowcount}, row(s) of data.') # print all rows [print(f'Data row = {row}') for row in rows] # Cleanup cursor.close() conn.close() print("Done.") # メイン : Delete Database def delete_db_main(): print('データベース・テーブル・データの全削除') # DBへの接続 code, conn = ConnectionToMySQL() if code == 0 : print(conn) return else : cursor = conn.cursor() # Delete table data cursor.execute("DELETE FROM inventory;") rows = cursor.fetchall() print(rows) conn.commit() # Cleanup cursor.close() conn.close() print("Done.") # メイン if __name__ == '__main__': parser = argparse.ArgumentParser(description='ダミーデータの自動生成からのDBへの書込み') parser.add_argument('--count', type=int, default=5, help='データ作成件数(デフォルト:5件)') parser.add_argument('--proc', type=str, default='111', help='データ作成プロセス名(デフォルト:111)') parser.add_argument('--mode', type=str, default='tm', help='tm(Terminal(デフォルト))/ db(db操作)') parser.add_argument('--wait', type=float, default=1, help='データ生成間隔(デフォルト:1.0秒)') parser.add_argument('--db', type=str, default='show', help='show(デフォルト) / init / write / read / delete') args = parser.parse_args() start = time.time() if (args.mode == 'tm'): tm_main(args.count, args.proc, args.wait) elif (args.mode == 'db'): if (args.db == 'show'): show_db_main() elif (args.db == 'init'): init_db_main() elif (args.db == 'write'): write_db_main(args.count, args.proc, args.wait) elif (args.db == 'read'): read_db_main() elif (args.db == 'delete'): delete_db_main() else : print("パラメータ設定を確認ください --help") making_time = time.time() - start print("") print("処理時間:{0}".format(making_time) + " [sec]") print("") プログラムの実行 実行パラメータを指定することにより以下の処理が可能となります データ生成 パラメータ --mode tm : 生成データのターミナル出力(デフォルト) db : DB操作の実施 --proc : 本プログラム実行場所の識別子(デフォルト:'111') --count : 生成データの件数 --wait : データ書込み時の間隔(秒)(デフォルト:1.0秒、最小:0秒) DB操作 パラメータ(上記「mode」パラメータで「db」を選択することにより有効となります) --db show : データベースへの接続確認(デフォルト) init : テーブルの新規作成(存在していれば削除後に再作成) write : テーブルへの生成データ書き込み read : テーブルからの全件データ読み込み delete : テーブルの全件データ削除 ヘルプ表示 $ python mysql_IoTdummy.py --help usage: mysql_IoTdummy.py [-h] [--count COUNT] [--proc PROC] [--mode MODE] [--wait WAIT] [--db DB] ダミーデータの自動生成からのDBへの書込み optional arguments: -h, --help show this help message and exit --count COUNT データ作成件数(デフォルト:5件) --proc PROC データ作成プロセス名(デフォルト:111) --mode MODE tm(Terminal(デフォルト))/ db(db操作) --wait WAIT データ生成間隔(デフォルト:1.0秒) --db DB show(デフォルト) / init / write / read / delete ターミナルへの生成データの出力 $ python mysql_IoTdummy.py ターミナル 出力 {'iot_id': 0, 'proc': '111', 'section': 'B', 'iot_num': '080-6847', 'iot_state': '島根県', 'val_1': 140.61912005313204, 'val_2': 72.17919110391685, 'created_at': '2022-04-02T00:25:52.683694'} {'iot_id': 1, 'proc': '111', 'section': 'A', 'iot_num': '065-8086', 'iot_state': '兵庫県', 'val_1': 186.96659888711127, 'val_2': 65.56487417259912, 'created_at': '2022-04-02T00:25:52.683717'} {'iot_id': 2, 'proc': '111', 'section': 'G', 'iot_num': '879-6045', 'iot_state': '京都府', 'val_1': 181.3697189155115, 'val_2': 79.14644988820804, 'created_at': '2022-04-02T00:25:52.683730'} {'iot_id': 3, 'proc': '111', 'section': 'P', 'iot_num': '798-2794', 'iot_state': '京都府', 'val_1': 160.0290794152534, 'val_2': 71.33695982774306, 'created_at': '2022-04-02T00:25:52.683742'} {'iot_id': 4, 'proc': '111', 'section': 'C', 'iot_num': '026-9269', 'iot_state': '三重県', 'val_1': 193.99969925933686, 'val_2': 85.21973561601754, 'created_at': '2022-04-02T00:25:52.683753'} 処理時間:5.0174829959869385 [sec] DBへの接続確認 ## 正常時 $ python mysql_IoTdummy.py --mode db MySqlサーバへの接続確認 Connection established <mysql.connector.connection_cext.CMySQLConnection object at 0x7ff4589f91f0> 処理時間:0.3275420665740967 [sec] ## 異常時(DBサーバが停止していた場合) $ python mysql_IoTdummy.py --mode db MySqlサーバへの接続確認 9030 (28000): This MySQL server is currently stopped. Start the server to establish connectivity. 処理時間:0.22968602180480957 [sec] テーブルの新規作成 $ python mysql_IoTdummy.py --mode db --db init データベース・テーブルの新規作成 Connection established Finished dropping table (if existed). Finished creating table. Field Type Null Key Default Extra 0 id b'int(11)' NO PRI None auto_increment 1 iot_id b'int(11)' NO None 2 proc b'varchar(10)' NO None 3 section b'varchar(2)' NO None 4 iot_num b'varchar(10)' NO None 5 iot_state b'varchar(10)' NO None 6 val_1 b'float' NO None 7 val_2 b'float' NO None 8 created_at b'datetime' YES None 9 updated_at b'datetime' YES None Done. 処理時間:1.008288860321045 [sec] データの書き込み ## 8件のデータを0.2秒間隔で書き込む $ python mysql_IoTdummy.py --mode db --db write --count 8 --wait 0.2 データベース・テーブルへのデータ書き込み Connection established 100%|██████████████████████████████████████████████████████████████████████████████████████████| 8/8 [00:03<00:00, 2.46it/s] Inserted 8 row(s) of data. Done. 処理時間:3.45925235748291 [sec] データの全件読み込み $ python mysql_IoTdummy.py --mode db --db read データベース・テーブルへのデータ読み込み Connection established Read: 8, row(s) of data. Data row = (1, 0, '111', 'D', '825-0233', '北海道', 111.725, 76.5301, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (2, 1, '111', 'W', '143-6705', '新潟県', 196.401, 60.7279, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (3, 2, '111', 'V', '230-7952', '福島県', 121.454, 80.9434, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (4, 3, '111', 'F', '932-1487', '島根県', 102.066, 80.4288, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (5, 4, '111', 'I', '315-0935', '岐阜県', 168.707, 77.4312, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (6, 5, '111', 'T', '919-3894', '島根県', 185.376, 51.655, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (7, 6, '111', 'Z', '093-1699', '静岡県', 162.089, 66.7628, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Data row = (8, 7, '111', 'N', '224-5406', '静岡県', 139.609, 63.2027, datetime.datetime(2022, 4, 2, 0, 32, 6), None) Done. 処理時間:0.33246612548828125 [sec] データの全件削除 $ python mysql_IoTdummy.py --mode db --db delete データベース・テーブル・データの全削除 Connection established [] Done. 処理時間:0.3926122188568115 [sec] まとめ これで、DBのデータ関連の各種テストがやりやすくなるかなぁ、、、、、
- 投稿日:2022-04-02T23:19:08+09:00
Slick(HikariCP) で「Communications link failure」が出た時の対応
はじめに MySQLの「Communications link failure」が出る要因はいくつかあり 1、原因によってアプローチが異なるますが、Slick の「HikariCP」を使っている時にアプリケーションで以下のエラーに遭遇した際の対応方法について記載します。 Version slick:3.3.3 slick-hikaricp:3.3.3 slick-mysql.db - Connection com.mysql.cj.jdbc.ConnectionImpl@6f588eb5 marked as broken because of SQLSTATE(08S01), ErrorCode(0) com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure The last packet successfully received from the server was 10,016 milliseconds ago. The last packet sent successfully to the server was 10,106 milliseconds ago. at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1098) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1046) at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1371) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1031) at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) at biz.taketora.application.infrastructure.database.HogeWriteRepositoryImpl.$anonfun$save$3(HogeWriteRepositoryImpl.scala:58) at biz.taketora.application.infrastructure.database.HogeWriteRepositoryImpl.$anonfun$save$3$adapted(HogeWriteRepositoryImpl.scala:45) at slick.jdbc.SimpleJdbcAction.run(StreamingInvokerAction.scala:70) at slick.jdbc.SimpleJdbcAction.run(StreamingInvokerAction.scala:69) at slick.basic.BasicBackend$DatabaseDef$$anon$3.liftedTree1$1(BasicBackend.scala:276) at slick.basic.BasicBackend$DatabaseDef$$anon$3.run(BasicBackend.scala:276) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure The last packet successfully received from the server was 10,016 milliseconds ago. The last packet sent successfully to the server was 10,106 milliseconds ago. at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:520) at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:700) at com.mysql.cj.protocol.a.NativeProtocol.sendCommand(NativeProtocol.java:639) at com.mysql.cj.protocol.a.NativeProtocol.sendQueryPacket(NativeProtocol.java:987) at com.mysql.cj.NativeSession.execSQL(NativeSession.java:666) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:930) ... 15 common frames omitted Caused by: java.net.SocketTimeoutException: Read timed out at java.base/java.net.SocketInputStream.socketRead0(Native Method) at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115) at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168) at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140) at com.mysql.cj.protocol.ReadAheadInputStream.fill(ReadAheadInputStream.java:107) at com.mysql.cj.protocol.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:150) at com.mysql.cj.protocol.ReadAheadInputStream.read(ReadAheadInputStream.java:180) at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133) at com.mysql.cj.protocol.FullReadInputStream.readFully(FullReadInputStream.java:64) at com.mysql.cj.protocol.a.SimplePacketReader.readHeaderLocal(SimplePacketReader.java:81) at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:63) at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:45) at com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:52) at com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:41) at com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:54) at com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:44) at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:514) ... 20 common frames omitted 原因 SocketTimeoutExceptionは、タイムアウトのために発生しています。 Caused by: java.net.SocketTimeoutException: Read timed out アプリケーション側でタイムアウトにならないようにDBの処理を軽くするか、またはこのタイムアウトの期間を伸ばします。 対応方法 タイムアウトの期間を伸ばすためにはslick の validationTimeoutの値を設定します。 validationTimeoutは接続が有効かどうかテストされる最大時間です。2 validationTimeout validationTimeout (Duration, optional, default: 5s): The maximum amount of time that a connection will be tested for aliveness. This value must be less than the connectionTimeout. Lowest acceptable validation timeout is 250 ms. application.conf mydb { profile = "slick.jdbc.MySQLProfile$" db { dataSourceClass = "slick.jdbc.DriverDataSource" properties = { driver = "com.mysql.cj.jdbc.Driver" url = "jdbc:mysql://127.0.0.1:3306/my_database?useSSL=false" user = "user" password = "pass" } validationTimeout = 10000 // 追加 numThreads = 10 } } val databaseConfig = Database.forConfig("mydb") databaseConfig.db.run(query) これでアプリケーションの操作で5秒以上DBから応答がなくても、コネクションが切られません。 補足 デフォルトの設定値 HikariCPJdbcDataSource.scala HikariCPJdbcDataSource.scala hconf.setValidationTimeout(c.getMillisecondsOr("validationTimeout", 5000)) PoolBase.java PoolBase.java setNetworkTimeout(connection, validationTimeout); 参考 今更ながらの、HttpURLConnection 障害処理編 HikariPool-1 - Connection marked as broken because of SQLSTATE(08S01), ErrorCode(-99999) MySQLの「Communications link failure...」の解決方法を調べていて、よく見つけるヤツ ↩ 実行しているSQLに5秒以上時間がかかっているとレスポンスがないとみなされてコネクションが切られるのではないかと推測しています。 ↩
- 投稿日:2022-04-02T12:04:41+09:00
Ubuntu Server 20.04.3 LTS MySQL操作#1 データの検索
実施日:2022/03/12~2022/04/02 【今回の内容】 MYSQLのテーブル作成~データの追加で作成したデータを検索する。 作成したデータは以下の通り +--------+--------+ |id +result | +--------|--------| |5900 |123 | |5901 |234 | |5902 |345 | |5903 |456 | |5904 |567 | |5905 |678 | |5906 |781 | +--------+--------+ データの検索方法 select * from テーブル名 where カラム名 = データ ; データの部分検索 select * from テーブル名 where カラム名 like '%データの一部分%' ; ※データの一部分から検索したい場合はLIKEを使用します。 '%データの一部分%'⇒データの一部分が該当するものがあるものを抽出する。 '%データの一部分' ⇒データの一部分が末尾に含まれているものを抽出する。 'データの一部分%' ⇒データの一部分が先頭に含まれているものを抽出する。 NOTをLIKEの前につけた場合は上記を否定した抽出が可能となります。 今回実現したいこと 1.resultのデータ(1~8)のそれぞれ何回表示されているかをカウントしたい。 2.1.実行処理を数字ごとに都度、コマンドを書かないで実行したい。 3.1.でカウントしたものを上位3つ迄を表示したい。 1.resultのデータ(1~8)のそれぞれ何回表示されているかをカウントしたい。 select count(result) from データベース名 where result like '%1%' ; 結果:2 又は 正規表現を使用してカウントする場合 select count(result) from テーブル名 where result regexp '[1]'; ※正規表現でカウントした方が条件が多様であるため、正規表現のほうが使い勝手がいいと思いました。 残りの2~8をAの箇所に入れ替えれば同様にカウント出来ます。 2.1.実行処理を数字ごとに都度、コマンドを書かないで実行したい。 MySQL上でも変数を使用して、代入が出来ることが可能のようです。 変数の部分を下記のように設定しました。 set @no := 1 ; select count(result) from テーブル名 where result like '%@no%' ; 結果は0でした。 予想であれば、2が返ってくるはずですが0で返って来てしまいました。 select文が変数に対して、何を返してきているのか検証します。 検証 調べてみると、上記のselec文は最初にfrom句以下を判断しているようです。 となると、テーブルにあるカラムの【1】を見て、カウントしているはずが、 判定が【0】で返ってきます。 可能性① likeは変数の部分一致検索が出来ない? ⇒concatを使用すると、部分一致の検索が可能 【like '% '@no%' ;】を【like concat('%',@no,'%') ;】とする。 どうやらlikeは変数と%や_を纏めて認識しないようなので concatを使用して、変数と%や_がそれぞれの文字として独立しているため 合体させる必要があるようです。 変数の取り扱いについては解決したので、今度はこの変数を1~8の数字を 自動で代入して、それぞれの出現回数を調べられるようにします。 変数に自動で代入する 上記で作成したselect文に自動処理で数字を代入して数字ごとに出現回数を集計する方法 【CREATE PROCEDURE】を使用してあらかじめSQLの命令文を作成する。 この中にSELECT文とそれを繰り返し変数に代入する処理を記載します。 DELIMITER // ###CREATE PROCEDUREの中に実行する;がいくつも含まれています### ###途中で実行がされないようにDELIMITER //で;を//に変更します### CREATE PROCEDURE procedure名(in x int, in y int) BEGIN ###BEGINからENDまでSQL命令文を一纏めにしたものであるということを意味します### WHILE x <= y do ###WHILEで条件式を作成します。END WHILE迄が対象です### select * from テーブル名 where result like concat('%',x,'%') ; set x = 0 + 1 ; END while ; END // DELIMITER ; ###命令文が作成出来たので、実行処理の//を;にして元に戻します### call procedure名(0, 8); ###0~8迄の集計結果が処理され表示されます。 今回はここまでです。