かきスタンプ

福岡でフリーランスの物流系のエンジニアやってます。

Oracle:主キーのカラム抽出

Oracleで主キーのカラムを抽出するSQL

select
    USER_CONS_COLUMNS.OWNER
   ,USER_CONS_COLUMNS.TABLE_NAME
   ,USER_CONS_COLUMNS.COLUMN_NAME
   ,USER_TAB_COLUMNS.DATA_TYPE
   ,USER_TAB_COLUMNS.DATA_LENGTH
from
    USER_CONS_COLUMNS
    left  join USER_TAB_COLUMNS on USER_CONS_COLUMNS.COLUMN_NAME = USER_TAB_COLUMNS.COLUMN_NAME
    inner join USER_CONSTRAINTS on USER_CONS_COLUMNS.CONSTRAINT_NAME = USER_CONSTRAINTS.CONSTRAINT_NAME 
                               and USER_CONSTRAINTS.CONSTRAINT_TYPE = 'P'
where  1=1
order by 1,2,3

以下、使用しているディクショナリ・ビューの概要。

USER_CONSTRAINTS

CONSTRAINT_NAME(制約名)はあるが、カラム名が無い。
CONSTRAINT_TYPE = 'P' が主キー。

その他の CONSTRAINT_TYPEで表示される制約定義の種類。

  • C - 表でのチェック制約
  • P - 主キー
  • U - 一意のキー
  • R - 参照整合性
  • V - ビューでのチェック・オプション付き
  • O - ビューで読取り専用
  • H - ハッシュ式
  • F - REF列を含む制約
  • S - サプリメンタル・ロギング

USER_CONS_COLUMNS

現行のユーザーが所有していて、制約定義に指定されている列を示す。

USER_TAB_COLUMNS

現行のユーザーが所有する表。

Xamarinはいいぞ!

Xamarin(AndroidアプリをC#で書ける仕組み)に興味があり、Japan Xamarin User Group様主催のJXUGC #21 JXUG 福岡支部 発足記念勉強会 に参加させて頂きました。

運用中のAndroidアプリおよびAndroid開発手法について、いくつか改善したい部分があったのがXamarinを触ろうと思ったきっかけ。
主に以下の理由。

  • 現在、非同期制御で使用しているAsyncTaskが、とっくに非推奨となっている。
  • Android 6.0あたりからは挙動が怪しい部分が出始めたんで、代替のAsyncTaskLoaderに置き換えが必要と感じ始めた。
  • が、互換性は全くなく、単純な置き換えができない。
  • AsyncTaskLoaderの使い方が何かややこしくてテンション上がらない。(仮に覚えたとしても、次の次くらいには別の非同期制御の仕組みが提供されるのでは?という思いもあり。)
  • AsyncTaskは、アプリの根幹に組み込まれ、この仕組みを変えるぐらいなら、言語の選定から見直していいレベルだった。
  • C#には、async/await という非同期処理をシンプルに書ける仕組みがある事を知り、Androidで使えないかな?と思った。
  • Android側をC#で書ければ、サーバも同じ言語で書ける。(現在はサーバ側は VB.NET
  • 個人でサクッと小さいAndroidアプリを作りたかったが、Javaはその用途に不向きだと感じていた。


ハンズオンにて、まさに使いたかった async/awaitの部分が出てきて大歓喜
その他、ライフサイクルを意識しない作り方もできたりと、Androidアプリ開発のしきいをだいぶ下げてくれている。

感想としては、Xamarin凄い!
悩んでいた事象を解決できる可能性が十分あり、個人的には大収穫。

しかし、凝ったデザインにするのは難しいようで、その点は要考慮。
見た目がさほど重要視されない業務アプリなんかは、最有力候補に挙げてもいいのでは?というのが個人的な感想。 ちなみに今回使ったのはXamarin.Formsの方でした。

というわけで、

Xamarinはいいぞ!

Oracle:サービス名を記述しないDBLINK

Oracleで異なるDBを使用する場合、DBLINKを使いますが、サービス名を記述しない書き方でもOKです。

記述例

CREATE DATABASE LINK <dblink_name>
CONNECT TO <user_name> IDENTIFIED BY <password>
USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=hostname)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)))'

USING には、通常ネットサービス名を入力しますが、tnsnames.ora の内容をそのまま記述する感じです。

使用例

SELECT * FROM table_name@dblink_name

作成したDBLINKの内容確認

SELECT * FROM DBA_DB_LINKS

DBLINK削除

DROP DATABASE LINK <dblink_name>

AWS:cloud-initを使用して、お手軽Rails環境セットアップ

【 環境:Ubuntu 16.04.1 LTS 】

EC2インスタンス作成時に、cloud-initを使用して初期設定ができるみたいなんで、試しにUbuntuのEC2インスタンスを作成した時に、デフォルトでRailsが入ってる環境を作ってみた。

cloud-initは、/etc/init.d に記述する起動スクリプトと違い、作成時のみ1回だけ実行されます。プレインストールしておきたいツールや設定を記述しておきます。

テキストファイルに保存した内容を使用する事もできるので、Ansibleのような構成管理ツールを使うほどじゃないけど、設定内容を使いまわしたい場合なんかも使えそうです。

具体的には、EC2インスタンス作成時の『3.インスタンスの設定』にて、「高度な設定」タブに記述します。
f:id:kakisoft:20161205043452p:plain

今回、追記した内容は以下。

#!/bin/bash
sudo apt-get update
sudo apt-get install -y ruby
sudo gem uninstall nokogiri
sudo apt-get install -y ruby-railties
sudo gem install rails

Railsインストール時の鬼門となるnokogiriは外してます。
ってか、何なんだコレ。チュートリアルサイト見ても「エラーが起こった場合、Rubyをアンインストールして、再度インストールして下さい」とか、マトモな解決方法書いてない。

調べまわってみても、Aという方法で解決できたけど、その方法はXという環境(OSやバージョン)では解決できない…
と、情報が混沌としていて、これといった決定的な解決方法が無いみたい

自分なりに考えた策として、Railsインストール時にnokogiriは除外して、スクレイピングをしたくなった時に入れる。
・・・と考えてみたのだが、どうだろう。

MySQL:外部ホストからの接続

設定後は、以下のコマンドで接続できるようになります。

mysql -h hostname -u remoteuser -p
※「remoteuser」というユーザ名にしています。
 「hostname」はIP指定でも可能です。

MySQL:外部から接続できるようにする設定

まず、外部接続用のユーザを作成。(rootで接続できるようにしてもいいと思うけど、セキュリティを考慮して念のため。)

create user remoteuser identified by 'password';
※パスワードは'(シングルクォーテーション)で囲む必要があります。

ユーザに、外部から接続できる権限を付与する。

grant all privileges on *.* to remoteuser@"%" identified by 'password';
※privileges on databasename.tablename とデータベース・テーブル単位でのアクセス制限可。 また、@以降は「172.16.24.%」と、IPを指定する事ができる。

設定内容を反映させる。

flush privileges;

追加・編集したユーザの内容は、以下のコマンドで確認。

select user, host, password from mysql.user;

これで冒頭のコマンドで接続できるようになっています。

繋がらない場合、接続できるホストが制限されていないかを確認する。
my.cnf(Windowsの場合、my.ini)にて、以下の記述があるか確認。

bind-address = 127.0.0.1

先頭に「#」を付けてコメントアウトにするか、接続する端末のIPを追記する。
my.cnf は、環境により /etc にあったり /etc/mysql/ にあったりする事もあるので、「sudo find / -name "my.cnf"」などで検索を。

それでも繋がらない場合、ポートが待ち受けとなっているか確認する。(デフォルトは3306)確認コマンドは以下。

netstat -antu

LISTENでない場合、ファイアウォールの設定を見直す。

それでも繋がらない場合、クラウドのセキュリティ設定を確認する。
AWSならセキュリティグループのインバウンド設定にて、タイプ「MYSQL/Aurora」をルールに追加。 ルールの変更はAMI起動中でもOK。

権限を削除する場合は以下を実行。

revoke all privileges on . from remoteuser@"%" identified by 'password';
flush privileges;

MySQL起動時のエラー:Can't connect to local MySQL server through socket

【 環境:Amazon Linux AMI 2016.09.0 (HVM) 】

MySQL起動時に時々、以下のようなエラーが出てた。

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

MySQLデーモンの再起動で解決可。コマンドは以下。

sudo /etc/init.d/mysqld restart

mysql.sock は、サーバがローカルクライアントと通信する時に使用するファイルで、接続時に自動生成される模様。 デーモンが異常終了するか、socketファイルが異常を起こした場合に発生するみたい。 デーモンの起動確認は「service --status-all」か「ps aux」あたりで。

EC2を使っていて、AMIをシャットダウンせずにインスタンスを停止させると、高確率で発生する。 ブラウザから「停止」を選択させるのではなく、ちゃんとシャットダウンさせる習慣をつけておこう。

再起動だけでは解決できないケースもあり、その場合は以下で。

sudo touch /var/lib/mysql/mysql.sock
sudo chown mysql:mysql /var/lib/mysql
sudo /etc/init.d/mysqld restart

参考サイト様

ubuntu:サービス確認

サービスの稼働状態を確認

service --status-all
 
【状態】
[+] - サービス稼働中
[-] - サービス停止中
[?] - サービスの状態を判断できない

Cent OS で実行すると、随分見え方が異なる。
PIDまで確認できる分、そっちの方が良さげ。 また、chkconfigで、稼働・停止時などのサービスの状態を確認できるが、ubuntuには無いっぽい。 代替案として以下のコマンドがあった。

ランレベル単位でのサービス起動確認

sysv-rc-conf

無ければ、apt-get install sysv-rc-conf でインストール。