SQL Server SET NOCOUNT

SET NOCOUNT

Transact-SQL ステートメントまたはストアド プロシージャで処理された行数を示すメッセージが結果セットの一部として返すか返さないかを設定します。

デフォルトでは SET NOCOUNT はOFFの状態です。
下の例で確認してください。

SQL Server SET NOCOUNT 実行例
SQL Server SET NOCOUNT 実行例

最初はデフォルトなので、そのままselect文やupdate文の処理行数を表示します。

次に SET NOCOUNT ON を実行したので、select文やupdate文共に処理行数の表示をしません。ただし @@ROWCOUNT は正常にカウントされています。

最後は SET NOCOUNT OFF を実行したので、再度select文やupdate文の処理行数を表示します。

このように SET NOCOUNT は、Transact-SQL ステートメントまたはストアド プロシージャで処理された行数を示すメッセージが結果セットの一部として返すか返さないかの設定ができます。

SET NOCOUNT ON

SET NOCOUNT ONが良く使われる場面は、ストアドプロシージャで処理を実行したときやクエリアナライザのメッセージタブに表示される「(– 件処理されました)」というメッセージ(DONE_IN_PROCメッセージ)を出さないようにできます。

ストアドプロシージャで各ステートメントの完了時にクライアントアプリケーションにステートメントが処理された行数をメッセージとして送っていると、自ら設定したPRINT文の表示するメッセージを見つけにくくなるばかりか、メッセージを処理するSMDBやサーバーからクライアントに送信するためネットワークに無駄な負荷を掛けます。
このため、ストアドプロシージャではSET NOCOUNT ONによるメッセージ抑制がパフォーマンス管理には有効と考えられています。

SET NOCOUNT OFF

上で示したメリットよりも、処理件数メッセージが送られて来る(表示される)方がメリットが高い場合は、デフォルトが OFF なので通常は何もしないで良いのですが、ON にした後に OFF にしたい場合などは、SET NOCOUNT OFF を実行します。

CSS 文字を太くする

CSSで文字を太くするには、font-weight を使います。

CSS 文字を太くする方法

数値指定で太さを支持する場合

これは100を指定時の文字の太さです。
これは200を指定時の文字の太さです。
これは300を指定時の文字の太さです。
これは400を指定時の文字の太さです。
これは500を指定時の文字の太さです。
これは600を指定時の文字の太さです。
これは700を指定時の文字の太さです。
これは800を指定時の文字の太さです。
これは900を指定時の文字の太さです。

キーワード指定で太さを指示する場合

これはlighterを指定時の文字の太さです。
これはnormalを指定時の文字の太さです。
これはbolderを指定時の文字の太さです。
これはboldを指定時の文字の太さです。

lighterは、数値200と同じ太さです。
nomalは、数値400と同じ太さです。
bolderは、数値500と同じ太さです。
boldは、数値700と同じ太さです。

CSS ではなくタグで太さを指示する場合

これはタグbで太さを指定しています。
これはタグstrongで太さを指定しています。

文字の太さは上のように数値で指定したり、キーワードやタグで指示したりできます。

でも、指定したにも関わらず太さが変わらないものが有ります。
数値で言うと100~500は同じくらいに見えますよね?600と700も同じで800と900も同じように見えます。

変わらないのは使用していいるフォントがその太さを持っていないためです。このブログでは特にフォントを指定していないので、デフォルトのフォントが採用されているはずです。

下にGoogleが開発したNoto Sans Japanese フォントを使用した例を表示します。どうですか?フォントの太さの違いが分かりましたか? 私のPC画面ではちゃんと太さが違って見えます。

これは100を指定時の文字の太さです。
これは200を指定時の文字の太さです。
これは300を指定時の文字の太さです。
これは400を指定時の文字の太さです。
これは500を指定時の文字の太さです。
これは600を指定時の文字の太さです。
これは700を指定時の文字の太さです。
これは800を指定時の文字の太さです。
これは900を指定時の文字の太さです。

CSSのコードを参考までに貼っておきます。なお、link タグは本来 head 部分に記述するものです。これが読み込めないとフォントを読み込めないので Noto Sans Japanese フォントで表示されません。

<link rel="stylesheet" href="//fonts.googleapis.com/earlyaccess/notosansjapanese.css">
<p >
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:100'>これは100を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:200'>これは200を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:300'>これは300を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:400'>これは400を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:500'>これは500を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:600'>これは600を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:700'>これは700を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:800'>これは800を指定時の文字の太さです。</span><br>
<span style='font-family: "Noto Sans Japanese", sans-serif;font-weight:900'>これは900を指定時の文字の太さです。</span><br>
</p>

下にGoogleが開発したNoto Sans JPフォントを使用した例を表示します。ちなみに私のPCではNoto Sans Japanese フォントに比べ、Noto Sans JPフォントでは違いが全然分かりませんでした。CSS の stylesheet の呼び出しに間違いがあるのかな?

これは100を指定時の文字の太さです。
これは200を指定時の文字の太さです。
これは300を指定時の文字の太さです。
これは400を指定時の文字の太さです。
これは500を指定時の文字の太さです。
これは600を指定時の文字の太さです。
これは700を指定時の文字の太さです。
これは800を指定時の文字の太さです。
これは900を指定時の文字の太さです。

Noto Sans Japanese と Noto Sans JP の違い

まず、「Noto Sans」と言うGoogleとAdobeが共同開発したフォントファミリーがあります。その中でWebで簡単に使えるのが、「Noto Sans Japanese」と「Noto Sans JP」フォントになります。他にも「Noto Sans CJK JP」フォントとかも有るのですが、Webでは「Noto Sans Japanese」と「Noto Sans JP」が使いやすいです。

Noto Sans Japanese と Noto Sans JP はGoogle fontsとして公開されていますが、Noto Sans Japanese はベータ版として認識されているようです。あとは、フォントの太さの段階(Weight)が7段階か6段階の違いがあります。下の表のようになっています。

WeightNoto Sans JapaneseNoto Sans JP
100Thinthin
200Light(無し)
300DemiLightlight
400Regularregular
500Mediummedium
700Boldbold
900Blackblack

数値600の指定はどちらも無いようです。
それにキーワードの異なっていますので、これから太さ指定をする時はキーワードを使わずに数値指定の方が無難そうですね。

以上、「CSS 文字を太くする」でした。

画像の横に文字を表示するには

画像の横に文字を表示するには

画像の横に説明文などが表示されているのを良く見かけます。下に表示されるより何となくわかりやすくて良いですよね。

画像の横に文字を表示するのは、画像 <img> に float 指定をすると簡単に実現できます。

例として下のUSBフラッシュメモリの紹介画面をTable を使わずに作ってみます。インターフェース :USB3.0 / USB2.0までが商品説明です。

持ち運びに便利なキャップレス!!ワンプッシュでコネクタを収納!
コネクターを傷つけないスライド・リトラクタブル(伸縮)タイプ!

シリーズ名 : USB3.0 Express ST1-2
タイプ :USBフラッシュメモリ
インターフェース :USB3.0 / USB2.0

 

CSS float で画像の回りこみを作ってみる

画像img要素にstyle=”float:left”を指定します。これで次の要素に対して左側に画像が回り込むようになります。その後、商品説明を書いて、最後に念のため style=”clear:both” で回り込みをクリアします。

持ち運びに便利なキャップレス!!ワンプッシュでコネクタを収納!
コネクターを傷つけないスライド・リトラクタブル(伸縮)タイプ!

シリーズ名 : USB3.0 Express ST1-2
タイプ : USBフラッシュメモリ
インターフェース : USB3.0 / USB2.0


<img src="https://memo.itsysgroup.com/wp-content/uploads/2018/04/042718_0554_USB1.jpg" alt="" width="209" height="218" style="float:left"/>
<p>
  持ち運びに便利なキャップレス!!ワンプッシュでコネクタを収納!
  <br>
  コネクターを傷つけないスライド・リトラクタブル(伸縮)タイプ!
</p>
<p>
  シリーズ名  : USB3.0 Express ST1-2<br>
  タイプ  : USBフラッシュメモリ<br>
  インターフェース  : USB3.0 / USB2.0
</p>
<br  style="clear:both">

簡単にイメージ通り表示されたと思います。
画像を商品説明の右側に回り込ませたい場合は、float:right を指定します。

ちなみにtable を使わないでと書きましたが、ふと商品説明は table を使った方が見易そうですね。やってみます。

持ち運びに便利なキャップレス!!ワンプッシュでコネクタを収納!
コネクターを傷つけないスライド・リトラクタブル(伸縮)タイプ!


シリーズ名USB3.0 Express ST1-2
タイプUSBフラッシュメモリ
インターフェースUSB3.0 / USB2.0

<img src="https://memo.itsysgroup.com/wp-content/uploads/2018/04/042718_0554_USB1.jpg" alt="" width="209" height="218" style="float:left;"/>
<p style="font-size:0.7em; font-weight: bold;">
  持ち運びに便利なキャップレス!!ワンプッシュでコネクタを収納!
  <br>
  コネクターを傷つけないスライド・リトラクタブル(伸縮)タイプ!
</p>
<br>
<div style="float:left;">
  <table>
    <tr><td>シリーズ名</td><td>USB3.0 Express ST1-2</td></tr>
    <tr><td>タイプ</td><td>USBフラッシュメモリ</td></tr>
    <tr><td>インターフェース</td><td>USB3.0 / USB2.0</td></tr>
  </table>
</div>
<br  style="clear:both">

うーん……変わらなかったかも……
ちなみに上の例では table要素を div要素で囲みましたが、table要素にstyle=float:left; width: 300px; のように float指定をしてもかまいません。div要素で囲んだ方が楽かなと思って囲んだだけですので。

以前『CSS floatの使い方』として段組み記事を書きましたので段組みが気になるなら少し覗いてみてください。

以上、「画像の横に文字を表示するには」でした。

SQL Server Create View

SQL Server Create View

新しいビュー(VIEW) を作ります。

ビューとは、テーブルの特定部分のデータを抜き出したり複数テーブルを結合し必要なデータセットを取得するための仮想的なテーブルです。
create table文で作成する物理的なテーブルとは異なり、ビューの実体はデータを持たちません。

構文

create table ビュー名 as selectステートメント

例文

従業員テーブルと部門テーブル、配属テーブルを結合させてあたかも1つのテーブルのように見せます。

SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
   QUOTED_IDENTIFIER, ANSI_NULLS ON;

--従業員テーブルの作成とデータ挿入
create table EMPLOYEE_V (
EMPLOYEE_ID nchar(5)
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
)
insert into [dbo].[EMPLOYEE_V] values('T0001','太郎','タロウ','1997-08-2','1','2013-03-30','2005347','住所','09001239876')
insert into [dbo].[EMPLOYEE_V] values('T0002','花子','ハナコ','1997-08-2','1','2013-03-30','2005347','住所','09001239876')
insert into [dbo].[EMPLOYEE_V] values('T0003','次郎','ジロウ','1997-08-2','1','2013-03-30','2005347','住所','09001239876')
insert into [dbo].[EMPLOYEE_V] values('T0004','三郎','サブロウ','1997-08-2','1','2013-03-30','2005347','住所','09001239876')


--部門テーブルの作成とデータ挿入
create table BUMON_V(
BUMON_CD nchar(3)
, BUMON_NAME nvarchar(20)
, primary key CLUSTERED (BUMON_CD)
)
insert into [dbo].[BUMON_V] values('001','営業部')
insert into [dbo].[BUMON_V] values('002','業務部')
insert into [dbo].[BUMON_V] values('003','製造部')
insert into [dbo].[BUMON_V] values('004','総務部')


--配属テーブルの作成とデータ挿入
create table HAIZOKU_V(
EMPLOYEE_ID nchar(5) 
, START_DATE date
, END_DATE date
, BUMON_CODE nchar(3)
, primary key CLUSTERED (EMPLOYEE_ID, START_DATE)
)
insert into [dbo].[HAIZOKU_V] values('T0001','2019/04/02','2020/06/09','004')
insert into [dbo].[HAIZOKU_V] values('T0002','2020/04/02','2020/06/09','002')
insert into [dbo].[HAIZOKU_V] values('T0003','2020/04/02',null,'002')
insert into [dbo].[HAIZOKU_V] values('T0004','2020/04/02',null,'002')
insert into [dbo].[HAIZOKU_V] values('T0001','2020/06/10',null,'001')
insert into [dbo].[HAIZOKU_V] values('T0002','2020/06/10',null,'003')

GO 

--Viewの作成
create View dbo.View_HAIZOKU
with schemabinding
as
select TH.EMPLOYEE_ID
, TH.BUMON_CODE
, TB.BUMON_NAME
, TE.NAME
, TE.KANANAME
 from dbo.HAIZOKU_V TH
inner join dbo.EMPLOYEE_V TE on TH.EMPLOYEE_ID = TE.EMPLOYEE_ID
inner join dbo.BUMON_V TB on TH.BUMON_CODE = TB.BUMON_CD
where TH.end_date is null

GO

--インデックの作成(従業員ID)
create UNIQUE CLUSTERED index IDX_View_HAIZOKU 
on View_HAIZOKU (EMPLOYEE_ID)

GO

--インデックの作成(部門コード)
create NONCLUSTERED index IDX_View_HAIZOKU2 
on View_HAIZOKU (BUMON_CODE)

GO

--ビューからデータを取得
select BUMON_NAME
, NAME
, KANANAME 
from View_HAIZOKU
order by BUMON_CODE

/*
drop view View_HAIZOKU
drop table EMPLOYEE_V
drop table BUMON_V
drop table HAIZOKU_V
*/

Viewの参照はテーブルと同じようにできます。
上の例の80-85行を参考にしてください。

ViewにINDEXを付ける

ViewにもINDEXを付けて高速化することができます。
上の例の68-76行を参考にしてください。
INDEXを作成するにはいくつ条件が有るので、エラーが出たらメッセージを確認して対応してください。

良く引っかかるのが次のことです。
1-3行のSET オプション。
Viewを作成する時に schemabinding キーワードを付ける必要があります。
上の例の場合、dboを付けてあるようにスキーマ名を付ける必要があります。
INDEXを付ける時に NONCLUSTERED で作成する前に、UNIQUE CLUSTERED で作成する必要があります。
他にも有るかも知れませんが、エラーが出たらその都度調べてください。

私はあまり View を使わないのでこの程度のことしかわかりません、参考になれば幸いです。

以上、「SQL Server Create View」でした。

SQL Server クラスタ化インデックス 非クラスタ化インデックス

SQL Server インデックスのクラスタ化とは

SQL Server でテーブル等にインデックスを作成する際に、クラスタ化インデックスにするか非クラスタ化インデックスにするか決めることができます。
その違いをメリット・デメリットを挙げて説明します。

その前にインデックス(INDEX)とは

その前にインデックスとは、検索対象のテーブルやビューに対して早く検索できるように、任意の列のデータもしくは複数の列のデータの組み合わせを基準にして、どのような順序で並んでいるかを管理している索引情報のことです。
インデックスを作る際に「この列の小さい順でインデックス作成」のように列や並びを指定してインデックスを作成作成します。

クラスター化インデックス

クラスタ化インデックスは、指定した条件で「実際のデータを並び替えて格納」します。
実際にデータを並び替えて格納しているため、テーブル毎にクラスター化インデックスは1つしか作成できません。
最もよく使われる検索条件に合わせてクラスタ化インデックスを作成します。

メリット

データが並び替えられて保存されているため、範囲データの抽出が速いです。
データが並び替えられて保存されているため、余分な領域を取りません。

デメリット

テーブル1つに対して1つしかクラスター化インデックスを作成できません。
データ挿入でデータ格納領域に対して溢れが起こった場合、その処理に時間が掛かります。

作成方法

インデックやPRIMARY KEYを作る時に「CLUSTERED」キーワードを使います。
例)create UNIQU CLUSTERED index インデック名
  primary key CLUSTERED (列名)

非クラスター化インデックス

非クラスタ化インデックスの場合は、テーブルの実際のデータの並び替えは実施せず(入れた順に格納)、インデックスで指定した列の値に対応するデータレコードへのポインタがインデックスファイルに格納されます。
ピンポイント検索は高速ですが、範囲検索はデータがバラバラに格納されているため、クラスタ化インデックスに比べ一般的に遅くなります。無いよりは早いですが……
メリット

1つのテーブルに複数のインデックスを作成できます。
データの挿入時、追記挿入になるためクラスタ化インデックスに比べて一般的に若干早くなります。

デメリット

上述の理由で範囲検索が遅いです。

まとめ

インデックスはデータ量が多くなると絶対に必要になります。
適切なインデックス作成は難しいですし、大規模システムでは特に当初の設計の見込み違いなどでデータ規模が変わるとインデックスを変える必要が出てくる可能性もあります。机上設計のみならず実地に試験をしてパフォーマンス管理を怠らないよに努めてください。

SQL Server tableを作成してみる

tableを作成してみる

データベースを作成し、ログインユーザーを作成登録したら、次はテーブルを作成してみましょう。 テーブルを作成する方法はいくつかあります。 今回は何も無いところから始めるため、新規にテーブルを作成してみます。

SQL文を発行してテーブルを作成してみる

testTable01と言う名前のテーブルを作成してましょう。 testTable01テーブルには販売日・商品名・販売数のデータを格納できるようにします。 カラムは以下のように設定します。 h-date date null無し p-name nvarchr(10) null無し h-num int null有り SQL文は以下の通りです。

create table testTable01(
 h-date date not null
, p-name nvarchar(10) not null
, h-num int null 
)

SSMSを 立ち上げます。
データベースを選択します。
メニューバーの「新しいクエリ」ボタンをクリックします。
SQL文を入力できるWindowが表示されます。

 

 

SSMSのテーブル作成機能を利用してテーブルを作成してみる

表示されたWindowに上のSQLを入力し、「!実行」ボタンをクリックします。「!実行」ボタンは「新しいクエリ(N)」の下あたりに有りますが、なければ探してください。

グラフィカルな操作でテーブルを作ることも出来ます。データベースを右クリックして「テーブル…」を選択すると MS ACCESS の操作イメージでテーブルが作成できます。

私のテストで使っている環境では『このバックエンド バージョンでは、データベース ダイアグラムまたはテーブルのデザインはサポートされていません。 (MS Visual Database Tools)』と表示されて使用できません。
バージョンを合わせると使用できるそうなのですが、SQL で書いてしまうので必要性を感じず放置したままになってます……
データベース ダイアグラムはリレーションを貼ったりするのに便利そうなのですが、これも私は使っていないので……安易に変更できるといろいろと問題が有りそうなので……

以上、「SQL Server tableを作成してみる」でした。
もう少し詳しい情報が知りたい場合は、「SQL Server Create Table」を参考にしてください。

SQL Server Create Table

Create Table テーブルを作成する

新しいテーブルを作成します。

構文

create table テーブル名 (
列名 データ型
, 列名 データ型
, 列名 データ型
, 列名 データ型
   ・
   ・
)

デフォルト値を設定したい場合は、
列名 データ型 default データ
のようにデータ型の後ろにデフォルト情報を追記します。

例文

良くある社員情報のテーブルを例に挙げて例文となるSQLを示します。
情報は「社員コード」「社員名」「社員カナ名」「生年月日」「性別」「入社年月日」「郵便番号」「住所」「電話番号」とします。

create table EMPLOYEE (
ID nchar(5)
, NAME nvarchar(20)
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
)

実行

テーブルの作成を実行し、正常に終了すると下のように「コマンドは正常に完了しました」と表示されます。

構文等の記述ミスがあると、メッセージ番号、レベル、状態、行の情報と大まかなエラー内容が表示されます。

例えば、IDの nchar を記述ミスして nhar とした場合、以下のようなエラーメッセージが表示されます。

メッセージ 2715、レベル 16、状態 6、行 1
列、パラメーター、または変数 #1: データ型 nhar が見つかりません。

Not NULL制約の追加

NOT NULL制約とは、テーブルにデータを追加(Insert)、更新(Update)する際、テーブル列に対する制約の一つで、その列に必ず「値」が登録される制約をとることです。

ここで言う「値」とは値が未設定の状態である「NULL」でない値のことです。
NULLとは、値が未設定の状態とも言えます。

NULLについては「データベースのNULL」に少しですが説明してありますので、NULLがピンとこない場合は参照してみてください。

構文 Not NULL制約付き

例えば上の EMPLOYEE テーブルにおいて、従業員の「NAME」の定義を NAME nvarchar(20) NOT NULL と指定し、「NAME」列のデータには必ず値を入れないと追加・更新できなようにします。

create table EMPLOYEE (
ID nchar(5)
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
)

実際に登録してNAME列にデータを入れずに追加(Insert)してみます。

Create Table NOT NULL制約付き
Create Table NOT NULL制約付き

左のオブジェクト エクスプローラーで確認すると、NAME が「NULL以外」となっているのがわかります。
実際にNULLを入れようとしても、見ての通りエラーになります。

ちなみに2行目の「’’」は空文字のことで、長さ0文字の文字列になります。
プログラム言語のなかには空文字もNULLも同じ扱いにする言語があるかもしれませんが、データベースではNULLと空文字は明確に違うので注意してください。

下に2行目の「KANANAME」をNULLにして登録したものの結果を載せます。
空文字はブランク表示になっていますが、NULLはNULと表示されます。

NULLと空文字の違い
NULLと空文字の表示の違い

Select文で取得する時も
NULLなら Select * from EMPLOYEE where KANANAME is NULL
空文字なら Select * from EMPLOYEE where NAME=”
となります。

UNIQUE制約(列制約)

UNIQUE制約は列に設定し、その列に格納されるデータの中には同じコードや名称などが無い唯一のデータになるように制約を掛けることです。

上の従業員テーブルEMPLOYEEでは、IDがそれに当たることが多いです。
IDをUNIQUE設定すると同じIDは挿入できなくなります。
尚、NULL を格納することができ、またテーブルに複数列作成できます。

列にUNIQUE制約を行う構文

create table テーブル名 (
列名 データ型 [制約名] UNIQUE
)
制約名は付けなくても可。

create table EMPLOYEE2 (
ID nchar(5) UNIQUE
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
)

ID列の後ろに UNIQUE を付けるだけです。

ここで同じIDを挿入しようとするとエラーになります。
『メッセージ 2627、レベル 14、状態 1、行 2
制約 ‘UQ__EMPLOYEE__3214EC26A59C0AD4’ の UNIQUE KEY 違反。オブジェクト ‘dbo.EMPLOYEE2’ には重複するキーを挿入できません。重複するキーの値は (T0001) です。』と今回は表示されました。尚、機械的な制約名にならないので制約名を付けるとエラーもわかりやすくなるかも。

UNIQUE列の追加エラー表示
UNIQUE列の追加エラー表示

UNIQUE制約(テーブル制約)

テーブル制約でのUNIQUE制約は、複数列の組み合わせでUNIQUEに設定できるようになっています。もちろん1つの列のみ設定もできますが。

下の例、テーブルEMPLOYEE2-1の場合は、ID列とYYYY列の組み合わせでUNIQUEになるように設定しています。IDがT0001の人が2人居たとしても、YYYYが2020と2019のように異なればOKです。

テーブルにUNIQUE制約を行う構文

create table テーブル名 (
列名 ・・・,
[制約名] UNIQUE (列名, 列名・・・)
)
制約名は付けなくても可。

create table EMPLOYEE2_1 (
ID nchar(5)
, YYYY nchar(4)
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
, unique (ID, yyyy)
)

ID列YYYY列を同一で挿入しようとすると下のようにエラーがでます。

UNIQUEテーブル制約時の列データの追加正常表示
UNIQUEテーブル制約時の列データの追加エラー表示

ID列YYYY列のどちらかを変えると同一ではなくなるので正常に挿入できます。

UNIQUEテーブル制約時の列データの追加正常表示
UNIQUEテーブル制約時の列データの追加正常表示

PRIMARY KEY制約(列)

PRIMARY KEY制約は列に設定し、その列に格納されるデータの中には同じコードや名称などが無い唯一のデータになるように制約を掛けることです。

上の従業員テーブルEMPLOYEEでは、IDがそれに当たることが多いです。
IDをPRIMARY KEY設定すると同じIDは挿入できなくなります。
UNIQUEとほぼ同じですが、NULL を格納することができません。INDEXが自動で作成されます。またテーブルに複数列の組み合わせで作成したい時は列制約ではなく、テーブル制約でPRIMARY KEYを設定することになります。

列にPRIMARY KEY制約を行う構文

create table テーブル名 (
列名 データ型 [制約名] PRIMARY KEY
)
制約名は付けなくても可。

create table EMPLOYEE3 (
ID1 nchar(5) primary key
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
)

ID列の後ろに PRIMARY KEY を付けるだけです。

ここで同じIDを挿入しようとするとエラーになります。

メッセージ 2627、レベル 14、状態 1、行 2
制約 ‘PK__EMPLOYEE__C49703DD6C96672F’ の PRIMARY KEY 違反。オブジェクト ‘dbo.EMPLOYEE3’ には重複するキーを挿入できません。重複するキーの値は (T0001) です。』と今回は表示されました。尚、機械的な制約名にならないので制約名を付けるとエラーもわかりやすくなるかも。

PRIMARY KEY列の追加エラー表示
PRIMARY KEY列の追加エラー表示

PRIMARY KEY制約(テーブル)

テーブル制約でのPRIMARY KEY制約は、複数列の組み合わせでPRIMARY KEYに設定できるようになっています。もちろん1つの列のみ設定もできますが。

下の例、テーブルEMPLOYEE2-1の場合は、ID列とYYYY列の組み合わせでPRIMARY KEYになるように設定しています。IDがT0001の人が2人居たとしても、YYYYが2020と2019のように異なればOKです。尚、NULL を格納することができませんし、INDEXも自動で作成されます。

テーブルにPRIMARY KEY制約を行う構文

create table テーブル名 (
列名 ・・・,
[制約名] PRIMARY KEY (列名, 列名・・・)
)
制約名は付けなくても可。

create table EMPLOYEE3_1 (
ID nchar(5)
, YYYY nchar(4)
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
, primary key (ID, yyyy)
)

FOREIGN KEY制約(テーブル)

FOREIGN KEY制約は指定した列の値を登録する時に、指定したテーブルの列の中に無くてはならないと言う制約です。
今まで上で使用してきた例題のテーブルで言うと、YYYY列がNENDOテーブルのYYYYになければならない場合に使います。

テーブルにFOREIGN KEY制約を行う構文

create table テーブル名 (
列名 ・・・,
[制約名] FOREIGN KEY (列名, 列名・・・) REFERENCES 参照テーブル名(参照列名)
)
制約名は付けなくても可。

下の例では参照先のテーブルが無いとエラーになるので、参照先のテーブル作成例も合わせて挙げています。
尚、参照先のテーブルの参照列にはPRIMARY KEYが設定されていないとエラーになります。テーブル設計時に注意しましょう。

挿入時、削除時の注意事項

EMPLOYEE4_1テーブルに挿入する時は、事前に参照先のテーブルYYYY4_1に挿入うデータ値が格納されている必要があります。
で削除時ですが、EMPLOYEE4_1からは普通に削除できるのですが、YYYY4_1から削除する際にはEMPLOYEE4_1で削除しようとするデータ値が使われているとYYYY4_1で削除時にエラーが発生します。データ整合性が保たれるためです。

create table YYYY4_1(
YYYY nchar(4)
primary key (YYYY)
)
create table EMPLOYEE4_1 (
ID nchar(5)
, YYYY nchar(4)
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
, foreign key (YYYY) references YYYY4_1(YYYY)
)

CHECK制約(テーブル)

CHECK制約はFOREIGN KEY制約に似ていて、その列に登録可能なデータ値をチェックするのですが、あくまでも登録時だけのチェックです。
FOREIGN KEY制約ではデータの整合性も保たれますが、CHECK制約では

テーブルにCHECK制約を行う構文

create table テーブル名 (
列名 ・・・,
[制約名] CHECK (条件式)
)
制約名は付けなくても可。

CHECK制約の条件式例

・列名1 > 10
・列名1 in (, , ,)
・列名1 between x and z
・列名1 > 10 AND 列名2 in (‘A’,’B’,’C’)

create table EMPLOYEE5_1 (
ID nchar(5)
, YYYY nchar(4)
, NAME nvarchar(20) NOT NULL
, KANANAME nvarchar(20)
, BATHDAY DATE
, SEX nchar(1)
, JOIN_DATE DATE
, POST_CODE nchar(7)
, ADDRESS nvarchar(100)
, TEL nvarchar(11)
, check (YYYY between '2010' and '2022')
)

check (YYYY in (select YYYY from [dbo].[YYYY4_1]))
のような使い方はできません。『このコンテキストではサブクエリは許可されません。スカラー式だけが許可されます。』とエラーになります。

以上、「SQL Server Create Table」でした。

尚、SQL Server にはデータベースを作成するとき、複数のストレージに渡って作ることができます。HDD(ハードディスク)の個数でパフォーマンスが変わってくるので、大規模システムでは複数のストレージを使うことが多いです。
そして、ストレージ毎にファイルグループを持つように設定し、ストレージを分けることで負荷分散を行います。
このファイルグループにそれぞれ名前を付けることができます。 デフォルトはPRIMARYで、後は任意に名前を付けられます。

テーブルやインデックを作る時に「on」指定でこのファイルグループを指定できます。
この辺りは基礎ではないので私も詳しく説明できませんが、知っておくことは大切ですので、追記しておきます。詳しく知りたい人は「SQL Server Create table on」で検索するといろいろ出てくると思います。検索してないので……多分。

中学生の校内試験の疑似偏差値

最近の中学校では校内の試験結果の偏差値を教えてもらえないと聞きました。
平均点と自己点数の比較では一目で成績が上がっているのが維持できているのか、はたまた下がっているのかを実感しずらいです。

そこで、平均点から簡易で求める疑似偏差値なるものを利用して実感できるようにしてみました。
成績の傾向をグラフで確認したいのでEXCELを使用しています。

無料のEXCELで作りましたので、EXCELを持っていなくても、「無料の Web 版 Office で作成、共有、コラボレーション」でEXCELを使えるようにすれば、疑似偏差値を使えるようになります。無料のWeb版Officeを使えるようになる方法がわからなけくても、検索すればすぐにその方法がわかると思います。

平均点から求める中学生の校内試験の疑似偏差値用のEXCELファイルは下からダウンロードしてください。ファイル名が変な名前になってしまっているので、ダウンロードを右クリックして「名前を付けてリンク先を保存」でファイル名を指定した方が後々使いやすいです。

ただし、疑似偏差値なので正確性に欠けます。
あくまでも参考値としてください。
それから、どんな風に見えるか確認するために適当な点数を入れてしまっているので、Dataタグの表の中の点数データを消してから利用して下さい。下に表示されている点数は表を参照しているだけなので、消すと参照が消えてしまうので消さないでください。表の点数を更新すると自動で更新されますので。

疑似偏差値算出の参考にしたホームページを紹介しておきます。
偏差値をお子さんにうまく説明できない時や疑似偏差値の算出を知りたい時にとても役立ちます。お勧めです。

道山ケイの中学生向け勉強方法専門サイト
中学生向け偏差値の求め方・出し方 ← 疑似偏差値算出参考

以上、平均点から「中学生の校内試験の疑似偏差値」を簡単に把握する紹介でした。

データベースのNULL

データベースのNULL

データベースを扱っていると「NULL」と言うデータを良く見かけます。
データベースの値の初期値もNULLです。

では、データベースのNULLとはどんなものなのでしょうか?

データベースのNULLは空

データベースのNULLは、登録されたデータが空であることを意味しています。
空とは未設定の意味にも取れますが、そこに登録すべき値が無いと言う方が正確だと思います。
なのでデータベースの値の初期値はNULLにしておくことが多いです。

データベースの仕組みでは、どんな値が登録されても何らかの意味を持つ可能性が有ると判断しますが、NULLだけ空の意味しか持たず、「IS NULL」判定の式があります。
NULLは特別なデータです。

データベース システム開発におけるNULLの扱い

更にNULLには空には違いがないのですが、「未知・不明 (Unknown)」 の場合と「適用不能・非存在 (Not Applicable, Inapplicable)」 の場合があります。

例えば、電話番号がNULLの場合
未知・不明のNULLは「電話はあるが番号分からない」
適用不能・非存在のNULLは「電話を持っていない」
の違いがあります。

システム的にはどのように解釈してもシステム内で統一した認識があればよいのですが、例えば、「開発運用初期は000-0000-0000 が入っていた場合、在りえない値なので電話番号を不明として扱う場合に登録しておいた」つもりが、改修の際にNULLでないため実際の値として扱い不具合が出たなど、上の例は極端ですがもっと複雑なデータの場合は往々にして不具合発生の温床となりますので注意が必要です。

NULL を含む演算

NULLを含む演算の結果は、多くがNULLとなります。

売り上げの集計をしていて、一つでもNULLデータが混入していると、結果はNULLとなります。
集計の加算(足し算)だけでなく、客単価等を求めるために割り算などを使った場合も客数がNULLなら結果はNULLになります。

思わぬNULLデータを含む演算による不具合は良く発生するので注意が必要です。

下の結果のようにNULLになります。

NULLを含む演算結果

NULLを取り扱う工夫

思わぬところで不具合が発生してしてしまうNULLですが、なるべくそうならないように工夫することが可能です。

1.テーブルの列に NOT NULL 制約をかける

テーブルの列に NOT NULL制約をかけてしまい、NULLデータを登録(追加・更新)できないようにしてしまう。
追加や更新時にエラーで落ちてしまう不具合が発生するが、エラーハンドリングも取りやすい。

2.適宜 NULL 判定を入れる

isnull関数を使いNULLを妥当な数値やデータに変えます。
妥当性はシステムの性格にもよるので何とも言えないですが、NULL判定を上手く使い予期せぬ不具合を未然に防ぐようにします。

先ほどの演算結果の一部をisnull関数で書き換えてみました。

isnull関数でNULLをチェック
isnull関数でNULLをチェック

このisnull関数の他にもCase文を使ってチェックすることも可能です。
とりあえず例を載せておきます。

Case文を使ってNULLをチェック
Case文を使ってNULLをチェック

NULLの扱いについては「SQL Server NULL」でも少し説明しています。

以上、データベースにおけるNULLについての簡単な説明でした。

StarServer スパムメール設定

StarServer スパムメール設定 の「オイオイ~」なところ

SterServer を使い始めて5か月が経とうとしています。
安いし安定しているし、WordPressの応答もそこそこ早いしかなり満足しています。

ですが。。。
スパムメールの設定をしようとして「オイオイ~」ってなってしまいました。

スパムメールの設定には、「スパムメールの有効/無効の設定、スパムメールとして特定したメールの件名に付ける任意のヘッダー文字列の設定」「ホワイトリストの設定」「ブラックリストの設定」を行うことになります。

本当はメール受信拒否が設定できるともっとありがたいのですが、格安なので仕方ないのでしょうね。。。

で、なにが「オイオイ~」となる残念なことだったかというと

StarServer ヘルプがヘルプになってない?!

ワンポイント!「ホワイトリスト」「ブラックリスト」

「ホワイトリスト」と「ブラックリスト」への追加フォーマットに全く触れていません。
これって100%使うユーザーが居ないと確信してるからでしょうかね?

そもそもスパム設定を有効にしたら「自動的に迷惑メールのチェックが行われる」と言う時点で、かなり迷惑な設定だって思わないのでしょうか・・・
私には自動でされるのは迷惑で、確実に指定したメールアドレスのみ、スパムメールとしたい希望があります。
あっ、格安なので仕方ないですね・・・

で、更にこんなことも

Netowl Q&A掲示板 の運営の対応がまさしく機械任せ

スパムメール設定のブラックリストについて

質問者の問いに、心ある人が答えています。
しかし、少し力及ばず残念な回答になっています。

更に心ある人はWeb上でマニュアルまで探してって、お疲れ様です・・・そしてこの記事を書いている私にとってもWeb検索をしてこのページを発見したので、更に探さずに済み、ラッキーだったと言うか、ありがたい回答でした。ありがとうございました。

さて、Netowlと言うStarServerと言うか「ネットオウル運営チーム」さんですか、運営チーム自身のマニュアル作成の不手際のせいで遭難者が出ているのに、また助け舟を出した方もボロボロなのに、あっさり「質問の閉め切り」のみを行ってしまった、恥ずかしくも機械任せ&責任放棄しております。

StarServer は気に入っているので、かなりがっかりですね・・・

StarServer スパムメール設定 の ブラックリストにドメインを設定する方法

批判だけしていても何なので・・・「StarServer でスパムメール設定 の ブラックリストにドメインを設定する方法」の一部わかっている部分のみ回答を書きます。

ドメインを設定いするためには、

*@example.com

のようにアスタリスクを付けると正常に動きました。
サブドメインはテストしていませんが、*@subdomain.example.com で行けると思いますが、どうでしょうか?
ちなみに、やはり心ある人の報告のとおり、 @example.com や example.com のみの場合は、正常に動作しませんでした。

以上、「StarServer スパムメール設定 の ブラックリストにドメインを設定する方法」でネットオウル運営チームの「オイオイ~」的な対応にふと思ったので愚痴をこぼしました。
私が StarServer のスパムメール設定 の ブラックリストにドメインを設定するために、試験的にいくつかのパターンで設定した結果ですので、フォーマットはこれだけでないと思います。%とかも使えるかもしてません。正規表現の置き換えまでは使えない気がしますが、パワーが余っている人が居たら是非試してください。
結果を教えてもらえると嬉しいです。