SQL Server トランザクション

トランザクション

トランザクション(transaction)とは、不整合を起こさせないための一連の操作の集合のことで、一連の操作全体が一つの単位とみなされます。
複数のSQLを発行してデータ操作をしても、トランザクションを正常に終了させないと、全くデータ操作をしなかったのと同じになるようにされています。

新幹線のチケット販売を考えたとき、支払と切符の販売はセットであり、片方だけでは不都合が起こることから、支払と販売はトランザクション管理されないといけないことが容易に想像できると思います。

トランザクションの開始

SQL Server でトランザクション処理を開始するには、’bigin tran’句を発行します。
トランザクションは’bigin tran tran名’と言うようにトランザクション名を付けることができます。
トランザクション名は 32 文字まで有効です。(超えた分は切り捨てられます)

SQL Server は分散処理もできるため、トランザクションを分散トランザクションとしても実行できます。
その他、マークを付けたりもできます。
また、おかしなことを言うようですが、ネストもできます。複雑なデータ操作だと必要になることあるそうです。
高度なトランザクション管理を行いたい場合は、より深く調査をしてください。

一般的な一連の操作で済む処置であれば(ほとんどがそうなると思うのですが。。。)、以下のように発行してください。


BEGIN TRAN T1

トランザクション終了

トランザクションを終了させるには、’commit’句を発行します。


COMMIT TRAN T1

トランザクションを中断する

何らかのトラブルがあり、トランザクションを中断させ、データ操作を無かったことにしたい場合に’rollback’句を発行します。
プログラムの中だとエラーハンドリンして、その中でロールバックさせるのが一般的です。


rollback

以下に簡単なトランザクションの例を載せておきます。

正常に終了するパターン:

create table tbl1 (a_cd nvarchar(9))
create table tbl2 (a_cd nvarchar(9))

declare @acd nvarchar(9)
set @acd='00001'

begin tran t1

begin try

  insert into tbl1 (a_cd) values (@acd)
  insert into tbl2 (a_cd) values (@acd)

  commit tran t1

end try
begin catch

  rollback

end catch

select * from tbl1
select * from tbl2

-----後処理
drop table tbl1
drop table tbl2

set @acd=1/0を入れエラーを起こさせたパターン:

create table tbl1 (a_cd nvarchar(9))
create table tbl2 (a_cd nvarchar(9))

declare @acd nvarchar(9)
set @acd='00001'

begin tran t1

begin try

  insert into tbl1 (a_cd) values (@acd)
  insert into tbl2 (a_cd) values (@acd)
  set @acd=1/0

  commit tran t1

end try
begin catch

  rollback

end catch

select * from tbl1
select * from tbl2

-----後処理
drop table tbl1
drop table tbl2

動かしてみるとわかりますが、rollbackも含め正常にトランザクション処理されています。

なお、テーブル変数を使うと、テーブル変数は持続性のあるデータベースの一部ではないため、トランザクションのロールバックによる影響を受けません。
ロールバックしてもデータは途中までの操作が有効になったままなので、トランザクション処理を行う時は要注意です。

以上、トランザクションの簡単な説明でした。

SQL Server リテラル

リテラル

SQL Serverにおいてリテラルとは、識別子によって表現する必要がない明示的な数値、テキスト、日時などのことです。
たとえば、数値リテラルは、’100’や’1000’などの数を示す値です。
テキスト(文字列)リテラル ‘SQL Server’ など、日時リテラルは’2017/12/15’などです。

数値リテラル

SQL Server では取り扱える型によって少しづつ指定が違います。
引用符では囲みません。

binary 型定数は 16 進数の文字列であり、0x というプレフィックスが付きます。
bit 型定数は数値の 0 または 1 で表します。
integer 型定数は数値文字列で表し、小数点を含まない整数である必要があります。
decimal 型定数は、小数点を含む数値文字列で表せます。
float 型定数と real 型定数は科学的表記法で表します。(101.5E5, 0.5E-2)
money 型定数は数値文字列で表し、オプションで小数点および通貨記号をプレフィックスとして付加することができます。

また、数値が正であるか負であるかを示すには、数値型定数に + または – 単項演算子を付加します。

テキスト(文字列)リテラル

英数字 (a ~ z、A ~ Z、および 0 ~ 9)、感嘆符 (!)、アット マーク (@)、および番号記号 (#) などの特殊文字を単一引用符で囲みます。
単一引用符で囲まれた文字列に単一引用符を埋め込む場合は、単一引用符を 2 つ続けて並べることで 1 つの単一引用符を表します。 文字列が二重引用符で囲まれている場合は該当しません。

文字列リテラルに N プレフィックスを付けると Unicode 文字列になります。

実はこのテキストリテラル、とても奥深いです。
私も深く掘り下げると理解できないところが出てきます。
UNICODEとか、照合順位とかいろいろありますので、興味がでたら調べてみてください。

日時リテラル

datetime 型を利用します
単一引用符で囲みます。

‘December 5, 1985’
‘5 December, 1985’
‘851205’
’12/5/98′
など、さまざま表記法があります。

以上、リテラルについての簡単な説明でした。

SQL Server INTERSECT

INTERSECT

INTERSECT は、ユニオンクエリと呼ばれ、1つのクエリ結果と別のクリエ結果の同じ行のみの結果を返します。
ユニオンクエリには、UNION, EXCEPT 句もあります。

ちなみに、SQL Server には、INTERSECT ALL はありません。

INTERSECT の使い方

1つの目のクエリ結果と、次のクリエ結果を比較し、同じ行(レコード)のみを結果として返します。

以下に簡単な例を書きます。
tble1の結果からtbl2と同じ結果(行)があるもののみ結果を返しています。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','3',1)

declare @tbl2 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000030','3',2)

select * from @tbl1
INTERSECT
select * from @tbl2

left join 句を使用して同じこともできますが、INTERSECT 句を使った方がシンプルですね。

select t1.* from @tbl1 t1
left join @tbl2 t2
on t1.a_cd = t2.a_cd
and t1.b_kbn = t2.b_kbn
and t1.c_kbn = t2.c_kbn
where t2.a_cd is not null

以上、INTERSECT の簡単な使用方法でした。

SQL Server EXCEPT

EXCEPT

EXCEPT は、ユニオンクエリと呼ばれ、1つのクエリ結果から別のクリエ結果を差し引いて重複を取り除き結果を返します。
ユニオンクエリには、UNION, INTERSECT 句もあります。

ちなみに、SQL Server には、EXCEPT ALL はありません。

EXCEPT の使い方

1つの目のクエリ結果から、次のクリエ結果を差し引いて、重複を取り除き、結果を返します。

以下に簡単な例を書きます。
tble1の結果からtbl2と同じ結果(行)があるものを取り除き結果を返しています。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','3',1)

declare @tbl2 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000030','3',2)

select * from @tbl1
except
select * from @tbl2

left join 句を使用して同じこともできますが、EXCEPT 句を使った方がシンプルですね。

select t1.* from @tbl1 t1
left join @tbl2 t2
on t1.a_cd = t2.a_cd
and t1.b_kbn = t2.b_kbn
and t1.c_kbn = t2.c_kbn
where t2.a_cd is null

以上、EXCEPT の簡単な使用方法でした。

SQL Server UNION と UNION ALL

UNION と UNION ALL

UNION と UNION ALL は、ユニオンクエリと呼ばれ、2つ以上のクエリ結果を結合して返します。
ユニオンクエリには、EXCEPT, INTERSECT 句もあります。

UNION と UNION ALL の違い

2つ以上のクエリ結果を結合して返します。
違いは、すべての結果を返すか、重複した行(レコード)は一行にして返すかの違いです。
使用するデータによっては、重複データを取り除きたい場合もあるし、すべてのレコードが必要な場合もあるので、選択して使用します。

以下に簡単な例を書きます。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)

declare @tbl2 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)

select * from @tbl1
union
select * from @tbl2
order by a_cd

select * from @tbl1
union all
select * from @tbl2
order by a_cd

UNION , UNION ALL はクエリを結合するので、ネストなどもできます。
下の例は、tbl1とtbl2を先にUNION結合し、後からtbl3をUNION ALL結合しています。
()で順序をつけることができます。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)

declare @tbl2 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl2 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)

declare @tbl3 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl3 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl3 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl3 (a_cd,b_kbn,c_kbn) values ('000000020','2',2)
insert into @tbl3 (a_cd,b_kbn,c_kbn) values ('000000030','2',2)

select * from @tbl3
union all
(
select * from @tbl1
union
select * from @tbl2
)
order by a_cd

以上、UNION と UNION ALL の簡単な使用方法でした。

SQL Server NULL について

NULL

SQL文を書くとき、データがnullを取りうるか否かを常に意識する必要があります。
nullを検索するためには、明示的に is null や is not null を使用する必要があります。

NULL を扱う

null 値を許可している場合、かつ、その値が検索対象になっている場合は先の is null や is not null を使用します。
簡単な例を下に示しておきます。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000040','3',null)
 
select * from @tbl1

select * from @tbl1 where c_kbn = 0 or c_kbn <> 0 

select * from @tbl1 where c_kbn is null

select * from @tbl1 where c_kbn is not null

select a_cd, b_kbn, isnull(c_kbn, -1) from @tbl1

select a_cd, b_kbn,
    case
    when c_kbn is not null then c_kbn
    when c_kbn is null then '-1'
	end
from @tbl1

更にANSI/ISOのCOALESCE関数を使うこともできます。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000040','3',null)

select a_cd, b_kbn, coalesce(c_kbn, '-1') from @tbl1

この他、SQL Server では、ANSI_NULLS の設定で = , <> を使用できるようになる。

declare @tbl1 table(a_cd char(9), b_kbn char(1), c_kbn int)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000001','1',0)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000010','1',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000020','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000030','2',1)
insert into @tbl1 (a_cd,b_kbn,c_kbn) values ('000000040','3',null)

set ansi_nulls on

select * from @tbl1 where c_kbn = null
select * from @tbl1 where c_kbn <> null

set ansi_nulls off

select * from @tbl1 where c_kbn = null
select * from @tbl1 where c_kbn <> null

以上、null の扱いかたでした。

WindowsのDNSキャッシュをクリアする方法

WindowsのDNSキャッシュをクリアする方法

レンタルサーバーを変えていて、DNSの変更がきちんとされたかを調べたいときにDNSキャッシュが邪魔な時があります。
DNSキャッシュの削除方法を備忘録しておきます。

WindowsのDNSキャッシュをクリア・削除

コマンド一発です。
コマンドプロンプトで実行してください。

ipconfig /flushdns

DNSキャッシュがクリア・削除されたか確認

これもコマンド一発です。
コマンドプロンプトで実行してください。

ipconfig /displaydns

だらだらリストが出てこなければクリアされています。
クリアする前にipconfig /displaydnsを実施して状態を確認するとわかりやすいかも。

以上、WindowsのDNSキャッシュをクリアする方法でした。

楽天カードから不審なメールが来ました~

楽天カードから不審なメールが来ました~

本日2017/10/18 11:11 に楽天カードから不審なメールが来ました~。

打合せ中だったので、メールのタイトルを見て「おや??」と思ったのですが、スルーしました。
「おや??」の理由は、私、楽天カード持っていません。
なのに、「【楽天カード】ご請求予定金額のご案内」なるタイトルでメールがきてたので、不思議に思って。。。

打合せが終わって、お昼を食べながら、不審メールを見ていたのですが、いかにも怪しそうな感じがしないんですね。

楽天カード 不審メール

楽天カード 不審メール


普通の感じですよね。

でも、楽天カード持ってないですから、あきらかに不審メールです。
で、さっそく「楽天カード 不審メール」でググってみました。
出てきました。。。

楽天カードを装った不審なメールにご注意ください

楽天カードを装った不審なメールにご注意ください


URLは『楽天カードを装った不審なメールにご注意ください』です。

で、どう言った被害にあうか私自身は試してみるのも怖いので試していませんが、どうやらメール内のURLをタップorクリックすると、ウイルスに感染するなどの被害に遭う(可能性がございます)のそうです。
なので、メール内のURLは絶対にタップorクリックしてはいけません

楽天カードのNewsでの警告でも、
差出人が「楽天カード株式会社」となっていても、身に覚えのない内容のメールに記載されているURLは絶対にクリックせず、送られてきたメールそのものを削除していただきますよう、何卒宜しくお願いいたします。
となっています。
って、身に覚えにない内容ならまだしも、楽天カード使ってたら不審に思わないからタップorクリックすることもあるよね?って思いますが。。。

差出人メールアドレス(info@mail.rakuten-card.co.jp)はどうやら正規のメールアドレスのようです。成りすまして送っているのかと。
正規のメールアドレス(info@mail.rakuten-card.co.jp)なら余計にタップorクリックしちゃう人いるよね。

みなさん、不審なメールには注意しましょうね。
あっ、そういえば今日、葉書でも架空請求の案内来てました。
すごく重要なお知らせを装ってるのに、配達証明で送ってこない事態がすでに怪しいってバレバレですけどね。。。

詐欺や迷惑行為が多いので気をつけましょうね^^
以上、ちょっと気になったので報告でした。

robots.txt の使い方

robots.txt の使い方。。。の前に

先日、『IX Web Hosting ハッキングされた!』に書いた通りハッキングされたのですが、その後何も起こらず平穏な日々に戻っています。
ハッキングされたのは「趣味のブログ」サイトで被害自体はどうってことのないものでした。
勝手に時計を売るページを引っ張ってくるページを作られたのですが、参照先もどこかの企業のホームページを使っていました。

で、問題は、Googleの「Search Console」のクロールエラーが一向に減らないってことです。
404エラーなので、「Googlebot はこの URL をクロールできませんでした。この URL が存在しないページを指していることが原因です。一般に、404 が発生しても検索結果でのサイトの掲載順位が低下することはありませんが、このエラー情報を使用してユーザーの利便性を向上させることができます。」とある通り、影響はないのですが、気持ち悪くて。。。

Search Consoleのクロールエラー

Search Consoleのクロールエラー

robots.txt の使い方

そこで、robots.txt の出番です。
robots.txt とは、Google や Bing などのロボット型検索エンジンに対する命令(依頼?)を記述するためのファイルです。
例えば自分のページの一部を、検索エンジンのデータベースに登録されないように命令(依頼?)をします。

命令には、
 ・対象:User-agent
 ・許可:Allow
 ・拒否:Disallow
 ・通知:Sitemap
の記述があります。

User-agent

GooglebotやBingbotなど命令(依頼?)したいクローラーを指定します。
基本的には、「*」で全てのクローラーを対象にします。

Allow

クローラーの訪問をブロックしないディレクトリやページを指定します。
基本的には、ブロックしないディレクトリやページを許可する方法はとらないので、使わないケースが多いです。
ディレクトリを指定すると配下のページにも影響を及ぼします。

Disallow

クローラーの訪問をブロックするディレクトリやページを指定します。
基本的には、検索対象にしたくなページを指定することになりますが、写真などのディレクトリをインデックスされたくない場合などに使います。
「/」でサイト全体を、「/dir/」でdirディレクトリ以下全てのページを指定したことになります。
「/*.jpg$」で全てのjpgファイルに対した指定も可能です。

Sitemap

sitemap.xmlの場所(URL)をクローラーに通知します。
URLは絶対パスで記述します。

今回の robots.txt

User-Agent: *
Disallow: /asd.php
Disallow: /zxc.php
Disallow: /qwe.php

全てのbotに対して、
asd.php、zxc.php、qwe.phpへのインデックスを拒否するように依頼をしました。

「Search Console」のrobots.txt テスター

robots.txt テスターツールを使用すると、robots.txt ファイルでサイト内の特定の URL に対して Google のウェブクローラがブロックされているかどうかを確認できます。
一応、『robots.txt を使用して URL をブロックする robots.txt テスターで robots.txt をテストする』を貼っておきます。
具体的な使い方がわからない時は、robots.txt テスターでググると出てきます。

これでしばらくすると、エラー数も落ち着いてくると思うのですが。。。
減ってきたらまたここに追記します。
あっ、効果なくても報告します。

CSS id と class の違いと使い分け

id と class

CSS(スタイルシート)を書く際に、「特定のタグ・要素すべて」を指定して一括装飾することもありますが、「特定のタグ・要素」を装飾したい場合がほとんどです。
HTMLで指定できる属性は2種類あり、ご存知のid属性とclass属性です。
この id と class の 違い と どのように使い分ける か、迷うことがあります。

この id と class は、適当に使うのではなく、ちゃんとした設計思想があります(あるそうです。。。あると思います)。
そこで今回は、 id と class の違いと、その設計思想についてお話します。

id と class の違い

id と class の違いは、簡単に理解できます。

id は identification の略で、本来は身分証明とか身分証明書のことです。
身分証明とか身分証明書なので同じページ内に、同じ id を持つものは居てはなりません。
居た場合、エラーになるか、プログラム挙動がおかしくなります。

class は共通の性質を有する部類、種類、(学校の)クラス、学級、組などの意味がありますね。
共通の性質を有する組を表しているので、同じ Class に属するものが居てもおかしくないですね。

id と class の違いは判りましたか?
他と区別するために付けるものは id
他と共通するために付けるものは class
です。

id と class の使い分け

では、id と class の使い分けはどのように考えましょう?
id と class は両方付与しても構いません。
id の方が優先されるため、同じ指定なら id が優先されるのでそこは注意が必要ですし、使い方によっては良いケースでもあります。

で、 id と class の違いが理解できていれば、使い分けも知識としては理解できます。
他と区別するために付けるものは id
他と共通するために付けるものは class
です。

ただ、現実問題プログラムを組んで行くと適当になってきてしまい、class を id として使用したりします。
相当大きなページでも最近のPCやスマホは高機能なので、下手な作りでも高速に動いてくれるので問題もないのですが。

で、解決策として、ルールを作って使い方を変えましょうとか、決め打ち(命名ルールに従い)で主要なタグに id を付与しclassは後から追加しましょうとか、書いてある書籍をよく見かけます。
間違いではないですし、有効に機能もする場合もあると思うのですが、それでは本末転倒というか、私は違和感を感じてしまいます。

操作はユニークか否かが、鍵

id か class かはオブジェクト指向の考えたを導入すると明確になります。
要は設計方針で id か class かも決められるます。
でも、オブジェクト指向なんて言われても困りますよね。。。

で、まずは操作が「共通して行われるもの」か、ユニークなもので「共通化されないもの」かを判定します。

操作が共通して行われるもの、背景色や文字種類・大きさ、その他何でも一度に指定して一度に更新したい操作には class を使います。
たとえ今は一つのタグに対してであっても、拡張したり、他のページにコピペで使用したりもありますので、操作を共通で行うものと判断出来たら class にします。

逆にユニークなもので共通化されないものの場合は、間違いを防ぐために id を使用します。
例えばいくつも必須入力テキストがあり、各々の入力判定の結果OKなら緑、NGなら赤にバックグランドを変える場合は、共通部分は class で、バックグラウンド色は id で指定するようにします。

設計思想によって、class を追加、削除するプログラムを書くと上の説明とはことなる考えたが必要になります。
設計思想によって、コロコロ変わってしまうので、「ルールを作って使い方を変えましょうとか、決め打ち(命名ルールに従い)で主要なタグに id を付与しclassは後から追加しましょう」とか結果曖昧な表現になってしまうのですね。

今回は、「操作はユニークか否か」で使い分ける方法を紹介しましたが、これが絶対ではなく、あくまでも一例です。
大きくないWebページなら、変な使い方でも問題ないです。
大きなWebページでは、ごちゃごちゃして、class を触ったら、意図しないタグで意図しない変化が出てしまったってことが良くあります。
id や class を管理をしてすっきりしたCSSを書きましょう。

以上、CSS id と class の違いと使い分けでした。