select句別名をgroup byやorder byで使用できるか確認

 

OracleSQL Serverはgroup byで別名を使用できない

(8.0.29)

drop table tab1 ;
create table tab1(col1 int,col2 int);
insert into tab1 values(1,1);
insert into tab1 values(1,2);
insert into tab1 values(2,1);
select * from tab1;

select col1,col2,col1+col2 col3 from tab1;
select col1,col2,col1+col2 col3 from tab1 order by col3;
select col1+col2 col3,count(*) from tab1 group by col3;

order by -> OK
group by -> OK

(19c)

drop table tab1 purge;
create table tab1(col1 int,col2 int);
insert into tab1 values(1,1);
insert into tab1 values(1,2);
insert into tab1 values(2,1);
commit;
select * from tab1;

select col1,col2,col1+col2 col3 from tab1;
select col1,col2,col1+col2 col3 from tab1 order by col3;
select col1+col2 col3,count(*) from tab1 group by col3;

order by -> OK
group by -> ORA-00904: "COL3": 無効な識別子です。

 

(23c)
order by -> OK
group by -> OK

(14)


drop table tab1 ;
create table tab1(col1 int,col2 int);
insert into tab1 values(1,1);
insert into tab1 values(1,2);
insert into tab1 values(2,1);
select * from tab1;

select col1,col2,col1+col2 col3 from tab1;
select col1,col2,col1+col2 col3 from tab1 order by col3;
select col1+col2 col3,count(*) from tab1 group by col3;

order by -> OK
group by -> OK

 

(2019)

drop table tab1 ;
create table tab1(col1 int,col2 int);
insert into tab1 values(1,1);
insert into tab1 values(1,2);
insert into tab1 values(2,1);
select * from tab1;

select col1,col2,col1+col2 col3 from tab1;
select col1,col2,col1+col2 col3 from tab1 order by col3;
select col1+col2 col3,count(*) from tab1 group by col3;

order by -> OK
group by -> 列名 'col3' が無効です。

 

プロシージャのオーバーロード

PostgreSQLオーバーロード可能
Oracleはパッケージ内のプロシージャならオーバーロード可能
MySQLSQL Serverオーバーロード不可

 

(8.0.29)

サポートされていない模様
念のため確認

drop procedure proc1;

delimiter //
create procedure proc1(
 in    param1 numeric
)
begin
  select param1;
end
//
delimiter ;

delimiter //
create procedure proc1(
 in    param1 varchar(30)
)
begin
  select param1;
end
//
delimiter ;


select *
from information_schema.routines
where routine_type = 'PROCEDURE'
and routine_name = 'proc1'\G


オーバーロードをサポートしていない

 

(19c)

-- 1. プロシージャの場合

create or replace procedure proc1(
 param1 in     number
)
as
begin
  dbms_output.put_line( param1 );
end;
/
show error;

create or replace procedure proc1(
 param1 in     varchar2
)
as
begin
  dbms_output.put_line( param1 );
end;
/
show error;

create or replace procedure proc1(
 param1 in     number
,param2 in     varchar2
)
as
begin
  dbms_output.put_line( param1 );
  dbms_output.put_line( param2 );
end;
/
show error;

select * from user_objects where object_type = 'PROCEDURE';

set serveroutput on
exec proc1(1);
exec proc1('A');
exec proc1(2,'B');

オーバーロードをサポートしていない

-- 2. プロシージャの場合

create or replace package pkg1
as
  procedure proc1  (param1 in number);
  procedure proc1  (param1 in varchar2);
  procedure proc1  (param1 in number, param2 in varchar2);
end;
/
show error;

create or replace package body pkg1
as
  procedure proc1(
   param1 in     number
  )
  as
  begin
    dbms_output.put_line( param1 );
  end;

  procedure proc1(
   param1 in     varchar2
  )
  as
  begin
    dbms_output.put_line( param1 );
  end;

  procedure proc1(
   param1 in     number
  ,param2 in     varchar2
  )
  as
  begin
    dbms_output.put_line( param1 );
    dbms_output.put_line( param2 );
  end;
end;
/
show error;

set serveroutput on
exec pkg1.proc1(1);
exec pkg1.proc1('A');
exec pkg1.proc1(2,'B');

オーバーロードをサポートしている

 

(14)


create or replace procedure proc1(
 param1 in     numeric
)
language plpgsql
as $$
declare
begin
  raise info '%', param1;
end;
$$;

create or replace procedure proc1(
 param1 in     varchar
)
language plpgsql
as $$
declare
begin
  raise info '%', param1;
end;
$$;

create or replace procedure proc1(
 param1 in     numeric
,param2 in     varchar
)
language plpgsql
as $$
declare
begin
  raise info '%', param1;
  raise info '%', param2;
end;
$$;


\df proc1

 

call proc1(1);
call proc1('A');
call proc1(2,'B');


オーバーロードをサポートしている

 

(2019)

サポートされていない模様
念のため試してみる

create or alter procedure proc1(
 @param1  numeric
)
as
begin
  print @param1;
end
go

create or alter procedure proc1(
 @param1  numeric
,@param2  varchar
)
as
begin
  print @param1;
end
go

select * from sys.objects where type in ('P');
go

exec proc1 1;
go
exec proc1 1,'A';
go

オーバーロードをサポートしていない

 

プロシージャの再帰呼び出し

 

4DBともにプロシージャの再帰実行は可能
ただし、MySQLはサーバパラメータの変更が必要

(8.0.29)

select @@max_sp_recursion_depth;
set session max_sp_recursion_depth=255;
select @@max_sp_recursion_depth;


drop procedure proc1;

delimiter //
create procedure proc1(
 in   n numeric
,out  m numeric
)
begin
  declare wk1 numeric;
  declare wk2 numeric;
  
  if n = 0 then
    set m = 0;
  elseif n = 1 then
    set m = 1;
  else
    call proc1(n-2,wk1);
    call proc1(n-1,wk2);
    set m = wk1+wk2;
  end if;
end
//
delimiter ;


call proc1(10,@wk1);
select @wk1;


drop procedure proc2;

delimiter //
create procedure proc2()
begin
  declare wk1 numeric;
  declare wk2 numeric;
  
  set wk1 = 0;
  while wk1 <= 20 do
    call proc1(wk1,wk2);
    select wk1,wk2;
    set wk1 = wk1 + 1;
  end while;
end
//
delimiter ;

call proc2();

 

--------------------------------

select @@max_sp_recursion_depth;
set session max_sp_recursion_depth=255;
select @@max_sp_recursion_depth;


drop procedure proc1;

delimiter //
create procedure proc1(
in   param1 numeric
)
begin
declare i int;
declare wk1 int;

if param1 = 0 then
  drop temporary table if exists rec;
  create temporary table if not exists rec(
   id    int
  ,col1  numeric
  ,col2  varchar(30)
  );
end if;

set wk1 = ( select count(*) from rec );
set i = 1;
while i <= 3 do
  insert into rec values(wk1 + i, param1 * 100 + i, param1 * 100 + i);
  set i = i + 1;
end while;


if param1 < 5 then
  call proc1(param1+1);
end if;

if param1 = 0 then
  select * from rec;
end if;

end
//
delimiter ;


call proc1(0);

 

 

 

(19c)
https://qiita.com/nkojima/items/a046b4c295ed75977626


create or replace procedure proc1(
  n in  number
, m out number
)
is
  wk1 number;
  wk2 number;
begin
  if n = 0 then
    m := 0;
  elsif n = 1 then
    m := 1;
  else
    proc1(n-2,wk1);
    proc1(n-1,wk2);
    m := wk1+wk2;
  end if;
end;
/
sho error


variable wk1 number
exec proc1(10, :wk1)
print wk1


set serveroutput on
declare
  wk1 number;
begin
  for i in 0..20 loop
    proc1(i,wk1);
    dbms_output.put_line(i||':'||wk1);
  end loop;
end;
/

 

--------------------------------

https://itsakura.com/oracle-plsql-function-ret

-- ネストした表のタイプ作成

drop type gar;
drop type grec;

create or replace type grec as object(
 id   int
,col1 number
,col2 varchar2(30)
);
/

create or replace type gar as 
table of grec;
/


set serveroutput on
create or replace procedure proc1(
 param1 in     number
,param2 out    gar
)
as
ar1 gar := gar();
ar2 gar := gar();
wk1 int;
begin

  for i in 1..3 loop
    ar1.extend;
    ar1(i) := grec(i,param1 * 100 + i, param1 * 100 + i);
  end loop;

  if param1 < 5 then
    proc1(param1+1,ar2);
    wk1 := ar1.count;
    for i in 1..ar2.count loop
      ar1.extend;
      wk1 := wk1+1;
      ar1(wk1) := ar2(i);
    end loop;
  end if;
  
  if param1 = 0 then
    for i in 1..ar1.count loop
      dbms_output.put_line('ar1(' || i || '): ' || ar1(i).col1 || ',' || ar1(i).col2 );
    end loop;
  else
    param2 := ar1;
  end if;
end;
/
show error;


declare
ar1 gar := gar();
begin
  proc1(0,ar1);
end;
/

 

 

(14)

create or replace procedure proc1(
  n in     numeric
, m out    numeric
)
language plpgsql
as $$
declare
  wk1 numeric;
  wk2 numeric;
begin
  if n = 0 then
    m := 0;
  elsif n = 1 then
    m := 1;
  else
    call proc1(n-2,wk1);
    call proc1(n-1,wk2);
    m := wk1+wk2;
  end if;
end;
$$;

 

call proc1(10, null);

 

do $$
declare
  wk1 numeric;
begin
  for i in 0..20 loop
    call proc1(i,wk1);
    raise info '%:%', i,wk1;
  end loop;
end;
$$;

 

--------------------------------

drop type if exists grec CASCADE;
create type grec as(
 id   int
,col1 numeric
,col2 varchar(30)
);

\df proc1

create or replace procedure proc1(
 param1 in     numeric
,param2 out    grec
)
language plpgsql
as $$
declare
ar1 grec
;
ar2 grec[];
wk1 numeric;
begin

  for i in 1..3 loop
    ar1[i].id   := i;
    ar1[i].col1 := param1 * 100 + i;
    ar1[i].col2 := param1 * 100 + i;
  end loop;

  if param1 < 5 then
    call proc1(param1+1,ar2);
    
    wk1 := array_upper(ar1, 1);
    for i in 1..array_upper(ar2, 1) loop
      wk1 := wk1+1;
      ar1[wk1] := ar2[i];
    end loop;
  end if;
  
  if param1 = 0 then
    for i in 1..array_upper(ar1, 1) loop
      raise info 'ar1(%): %,%', i,ar1[i].col1,ar1[i].col2;
    end loop;
  else
    param2 := ar1;
  end if;
end;
$$;


\df proc1


call proc1(0, null );

 

 

  • SQL Server

(2019)

create or alter procedure proc1(
  @n  numeric
, @m  numeric out
)
as
begin
  set nocount on;
  declare @wk1 numeric;
  declare @wk2 numeric;
  declare @wk3 numeric;
  declare @wk4 numeric;  
  if @n = 0
    set @m = 0;
  else if @n = 1
    set @m = 1;
  else
    begin
      set @wk1 = @n-2;
      set @wk2 = @n-1;
      exec proc1 @wk1 ,@wk3 out;
      exec proc1 @wk2 ,@wk4 out;
      set @m = @wk3+@wk4;
  end;
end
go

declare @wk1 numeric;
exec proc1 10,@wk1 out;
print @wk1;


set nocount on
declare @wk1 numeric;
declare @wk2 numeric;
set @wk1 = 0;
while @wk1 <= 20
begin
  exec proc1 @wk1 ,@wk2 out;
  print cast(@wk1 as varchar)+':'+cast(@wk2 as varchar);
  set @wk1 = @wk1 + 1;
end;
go

 

--------------------------------

 

create or alter procedure proc1(
 @param1  numeric
)
as
begin
  set nocount on;
  declare @i int;
  declare @wk1 int;
  declare @wk2 int;

  if @param1 = 0
    begin
      drop table if exists #rec;
      create table #rec(
       id    int
      ,col1  numeric
      ,col2  varchar(30)
      );
    end;

  set @wk1 = ( select count(*) from #rec );
  set @i = 1;
  while @i <= 3
    begin
      insert into #rec values(@wk1 + @i, @param1 * 100 + @i, @param1 * 100 + @i);
      set @i = @i + 1;
    end;

  if @param1 < 5
    begin
      set @wk1 = @param1+1;
      exec proc1 @wk1;
    end;
  if @param1 = 0
    select * from #rec;
end
go

exec proc1 0;

 

 

{IoT Core}3. IoT Core のセットアップ

 

https://catalog.us-east-1.prod.workshops.aws/workshops/b3e0b830-79b8-4c1d-8a4c-e10406600035/ja-JP

https://qiita.com/ekzemplaro/items/a95df050833204c266fb


モノ -- 証明書 -- ポリシー


-- 1. コマンド等のインストール

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

 

-- 1.2 jqインストール
sudo yum -y install jq


-- 2. IoT Core のセットアップ


-- 2.1 ポリシーの作成

vim policy01.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:*",
      "Resource": "*"
    }
  ]
}


aws iot create-policy \
--policy-name policy01 \
--policy-document file://policy01.json

aws iot list-policies

aws  iot get-policy \
--policy-name policy01


-- 2.2 モノの作成

aws iot create-thing \
--thing-name thing01

aws iot list-things

aws iot describe-thing \
--thing-name thing01


-- 2.3 証明書の作成

cd

aws iot create-keys-and-certificate \
--set-as-active \
--certificate-pem-outfile  certificate.pem.crt \
--private-key-outfile  private.pem.key

aws iot list-certificates

ls -ltr


-- 2.4 モノに証明書をアタッチ


aws iot attach-thing-principal \
--thing-name thing01 \
--principal arn:aws:iot:ap-northeast-1:999999999999:cert/1111111111111111111111111111111111111111111111111111111111111111

aws iot list-thing-principals \
--thing-name thing01

 

-- 2.5 証明書にポリシーをアタッチ


aws iot attach-principal-policy \
--principal arn:aws:iot:ap-northeast-1:999999999999:cert/1111111111111111111111111111111111111111111111111111111111111111 \
--policy-name policy01

aws iot list-principal-policies \
--principal arn:aws:iot:ap-northeast-1:999999999999:cert/1111111111111111111111111111111111111111111111111111111111111111

 

 

-- 3. デバイスのセットアップ

-- 3.1 AWS IoT Device SDK Python v2 を使った dummy client の設定


pip3 install --user awsiotsdk

mkdir -p ~/environment/dummy_client/certs/
cd ~/environment/dummy_client/

wget https://awsj-iot-handson.s3-ap-northeast-1.amazonaws.com/aws-iot-core-workshop/dummy_client/device_main.py -O device_main.py


-- 3.2 ルートCA証明書のダウンロード
cd ~/environment/dummy_client
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O certs/AmazonRootCA1.pem


-- 3.3 Device SDK を使ったデバイスの起動

aws iot describe-endpoint \
--endpoint-type iot:Data-ATS


cd
cp certificate.pem.crt ~/environment/dummy_client/certs
cp private.pem.key ~/environment/dummy_client/certs

cd ~/environment/dummy_client/
python3 device_main.py --device_name thing01 --endpoint 22222222222222-ats.iot.ap-northeast-1.amazonaws.com

-- 3.4 疎通テスト

AWS IoT Coreのコンソール画面の「MQTT テストクライアント」から実施


data/thing01

 

-- 4. クリーンアップ

-- モノの削除

aws iot list-things

aws iot detach-thing-principal \
--thing-name thing01 \
--principal arn:aws:iot:ap-northeast-1:999999999999:cert/1111111111111111111111111111111111111111111111111111111111111111


aws iot delete-thing \
--thing-name thing01


-- 証明書の削除


aws iot list-certificates

aws iot update-certificate \
--certificate-id 1111111111111111111111111111111111111111111111111111111111111111 \
--new-status INACTIVE


aws iot delete-certificate \
--certificate-id 1111111111111111111111111111111111111111111111111111111111111111 \
--force-delete

 

-- ポリシーの削除

aws iot list-policies

aws iot delete-policy \
--policy-name policy01

 

 

 

 

 

 

 

{IoT Events}シンプルな step-by-step 例

https://dev.classmethod.jp/articles/aws-iot-events-ga/

https://docs.aws.amazon.com/ja_jp/iotevents/latest/developerguide/iotevents-getting-started.html

https://docs.aws.amazon.com/ja_jp/iotevents/latest/developerguide/iotevents-simple-example.html


-- 1. コマンド等のインストール

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

-- 1.2 jqインストール
sudo yum -y install jq

 

-- 2. SNSトピック作成

aws sns list-topics
aws sns list-subscriptions

aws sns create-topic --name topic01
aws sns create-topic --name topic02

aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:999999999999:topic01 \
--protocol email \
--notification-endpoint hoge@example.com


aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:999999999999:topic02 \
--protocol email \
--notification-endpoint hoge@example.com

 


-- 3. IAMポリシー作成

vim policy01.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sns:*"
            ],
            "Effect": "Allow",
            "Resource": [ "arn:aws:sns:ap-northeast-1:999999999999:topic01",
                          "arn:aws:sns:ap-northeast-1:999999999999:topic02"
                        ]
        }
    ]
}


aws iam create-policy \
--policy-name policy01 \
--policy-document file://policy01.json


-- 4. IAMロール作成
vim role01.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "iotevents.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

aws iam create-role \
--role-name role01 \
--assume-role-policy-document file://role01.json


-- 5. ポリシーをロールにアタッチ
aws iam attach-role-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01 \
--role-name role01

 

-- 6. デバイスデータをキャプチャするための入力を作成します

vim input01.json 
{
  "inputName": "input01",
  "inputDescription": "Pressure readings from a motor",
  "inputDefinition": {
    "attributes": [
      { "jsonPath": "sensorData.pressure" },
      { "jsonPath": "motorid" }
    ]
  }
}

aws iotevents create-input  --cli-input-json file://input01.json

aws iotevents list-inputs

aws iotevents describe-input \
--input-name input01

 


-- 7. デバイスの状態を表すディテクターモデルを作成する

vim model01.json
{
  "detectorModelName": "model01",
  "detectorModelDefinition": {
    "states": [
      {
        "stateName": "Normal",
        "onEnter": {
          "events": [
            {
              "eventName": "init",
              "condition": "true",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "pressureThresholdBreached",
                    "value": "0"
                  }
                }
              ]
            }
          ]
        },
        "onInput": {
          "transitionEvents": [
            {
              "eventName": "Overpressurized",
              "condition": "$input.input01.sensorData.pressure > 70",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "pressureThresholdBreached",
                    "value": "$variable.pressureThresholdBreached + 3"
                  }
                }
              ],
              "nextState": "Dangerous"
            }
          ]
        }
      }, 
      {
        "stateName": "Dangerous",
        "onEnter": {
          "events": [
            {
              "eventName": "Pressure Threshold Breached",
              "condition": "$variable.pressureThresholdBreached > 1",
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:ap-northeast-1:999999999999:topic01"
                  }
                }
              ]
            }
          ]
        },
        "onInput": {
          "events": [
            {
              "eventName": "Overpressurized",
              "condition": "$input.input01.sensorData.pressure > 70",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "pressureThresholdBreached",
                    "value": "3"
                  }
                }
              ]
            },
            {
              "eventName": "Pressure Okay",
              "condition": "$input.input01.sensorData.pressure <= 70",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "pressureThresholdBreached",
                    "value": "$variable.pressureThresholdBreached - 1"
                  }
                }
              ]
            }
          ],
          "transitionEvents": [
            {
              "eventName": "BackToNormal",
              "condition": "$input.input01.sensorData.pressure <= 70 && $variable.pressureThresholdBreached <= 1",
              "nextState": "Normal"
            }
          ]
        },
        "onExit": {
          "events": [
            {
              "eventName": "Normal Pressure Restored",
              "condition": "true",
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:ap-northeast-1:999999999999:topic02"
                  }
                }
              ]
            }
          ]
        }
      }
    ],
    "initialStateName": "Normal"
  },
  "key" : "motorid",
  "roleArn": "arn:aws:iam::999999999999:role/role01"
}


aws iotevents create-detector-model  --cli-input-json file://model01.json

aws iotevents list-detector-models


aws iotevents describe-detector-model \
--detector-model-name model01

 

-- 8. ディテクターへの入力としてメッセージを送信する

echo -n '{"motorid": "Fulton-A32", "sensorData": {"pressure": 80, "temperature": 39} }' | base64

 

vim high.json
{
  "messages": [
    {
      "messageId": "00001",
      "inputName": "input01",
      "payload": "eyJtb3RvcmlkIjogIkZ1bHRvbi1BMzIiLCAic2Vuc29yRGF0YSI6IHsicHJlc3N1cmUiOiA4MCwgInRlbXBlcmF0dXJlIjogMzl9IH0="
    }
  ]


aws iotevents-data batch-put-message --cli-input-json file://high.json

警告メールの受信確認


echo -n '{"motorid": "Fulton-A32", "sensorData": {"pressure": 60, "temperature": 29} }' | base64


vim normal.json
{
  "messages": [
    {
      "messageId": "00002",
      "inputName": "input01",
      "payload": "eyJtb3RvcmlkIjogIkZ1bHRvbi1BMzIiLCAic2Vuc29yRGF0YSI6IHsicHJlc3N1cmUiOiA2MCwgInRlbXBlcmF0dXJlIjogMjl9IH0="
    }
  ]


aws iotevents-data batch-put-message --cli-input-json file://normal.json


sed -i 's/"messageId": "00002"/"messageId": "00003"/' normal.json
aws iotevents-data batch-put-message --cli-input-json file://normal.json

sed -i 's/"messageId": "00003"/"messageId": "00004"/' normal.json
aws iotevents-data batch-put-message --cli-input-json file://normal.json


復旧メールの受信確認

 

-- 9. クリーンアップ


-- ディテクターモデルの削除

aws iotevents list-detector-models


aws iotevents delete-detector-model \
--detector-model-name model01


-- 入力の削除

aws iotevents list-inputs

aws iotevents delete-input \
--input-name input01

 

-- IAMロールの削除
aws iam list-roles | grep role01

aws iam detach-role-policy \
--role-name role01 \
--policy-arn arn:aws:iam::999999999999:policy/policy01


aws iam delete-role --role-name role01


-- IAMポリシーの削除
aws iam list-policies | grep policy01

aws iam delete-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01

 

-- SNSトピック削除
aws sns list-topics
aws sns list-subscriptions


aws sns unsubscribe --subscription-arn arn:aws:sns:ap-northeast-1:999999999999:topic01:11111111-1111-1111-1111-111111111111
aws sns delete-topic --topic-arn arn:aws:sns:ap-northeast-1:999999999999:topic01

aws sns unsubscribe --subscription-arn arn:aws:sns:ap-northeast-1:999999999999:topic02:22222222-2222-2222-2222-222222222222
aws sns delete-topic --topic-arn arn:aws:sns:ap-northeast-1:999999999999:topic02