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 を使用する必要があります。

また、SQL Server で NULL 値を別の値にチェック後に変換するには、ISNULL 関数を使用します。

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

ISNULLでNullを置換する

ISNULLでNULLを他の文字に置き換える方法もありますので紹介しておきます。

構文:ISNULL(チェック対象, 変換したい文字列)
ISNULLの第1パラメータの値がNULLであれば、第2パラメータの文字列を返します(変換します)。
NULLでなければ、第1パラメータの値をそのまま返します。

declare @val integer

set @val = null
select isnull(@val, 1)

set @val = 0
select isnull(@val, 1)

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

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

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

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

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

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

ipconfig /flushdns

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

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

ipconfig /displaydns

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

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

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 の違いと使い分けでした。

SQLSERVER EXISTS、NOT EXISTS

SQLSERVER EXISTS、NOT EXISTS

EXISTS と NOT EXISTS

サブクエリの導入にキーワード EXISTS を使用した場合、そのサブクエリは「存在検査」として機能します。
NOT キーワードを付けた場合、そのサブクエリは「非存在検査」として機能します。

サブクエリの WHERE 句では、
・ データ抽出されるテーブル と 存在を試されるテーブル との リンク条件を指定します。
・ 存在を試されるテーブル の検索条件を指定します。
このことにより、このサブクエリから返される行が存在するかどうかがテストされます。
サブクエリは実際にはデータを生成せず、TRUE または FALSE の値を返します。

WHERE [NOT] EXISTS (subquery)

EXISTS演算子とは

EXISTS 演算子は、副問い合せの結果が存在するかを調べるときに使用します。
このとき、副問い合せの結果が存在するとき真になります。

NOT EXISTS演算子とは

NOT EXISTS 演算子は、副問い合せの結果が存在しないかを調べるときに使用します。
このとき、副問い合せの結果が存在しないとき真になります。

EXISTS、NOT EXISTS のテストサンプル

以下にテストSQLを載せておきます。
@tbl1には、id,kbn,pointの三項目
@tbl2には、id,kbn,priceの三項目
point,priceはランダムで数値が入ります。

@tbl1 と @tbl2は、同じid(kbnも)が入ります。
@tbl2のpriceの条件に合わせて、存在する存在しないをテストし、@tbl1のレコードを取得しています。

declare @tbl1 table(
    id int,
    kbn nchar(10) ,
    point int
)

declare @tbl2 table(
    id int,
    kbn nchar(10) ,
    price int
)

declare @start_id as int
set @start_id=0
 
while @start_id < 10
    begin
        print @start_id
        insert into @tbl1 values(@start_id, @start_id % 3, @start_id * Rand() * 10)
        insert into @tbl2 values(@start_id, @start_id % 3, @start_id * Rand() * 100)
        set @start_id = @start_id +1
    end

select * from @tbl1
select * from @tbl2

/* EXISTS */
/* テーブル@tbl2のpriceが200より大きなレコードを取得し、@tbl1の該当するレコードを表示する*/
select * from @tbl1 t1
  where EXISTS (
   select * from @tbl2 t2
     where t1.id= t2.id     --レコードのリンク
     and t2.price >= 200  --条件
 );


/* NOT EXISTS */
/* テーブル@tbl2のpriceが200より大きなレコードを取得し、@tbl1の該当しないレコードを表示する*/
select * from @tbl1 t1
  where NOT EXISTS (
    select * from @tbl2 t2
    where t1.id= t2.id     --レコードのリンク
    and t2.price >= 200  --条件
 );

IN 句と INNER JOIN 句 と比較

ちなみに、EXISTはINよりも速いとか、EXISTSは INNER JOIN より遅いだとか、良く耳にしますが、実際どうなんでしょうね?
個人的には、条件や状況によって違うのではないかと考えています。
Indexの有無、テーブルの大きさ、暗黙的な変換の有無、直前に使用テーブルにアクセスしてた等々条件や状況によって変わってくると。
とりあえず簡単なパフォーマンステストをしてみたいと思います。
サンプルSQLは以下の通りです。
自前の環境で、条件を変えてテストしてみてください。

create table #tbl1 (
    id int,
    kbn nchar(10) ,
    point int
)

create table #tbl2(
    id int,
    kbn nchar(10) ,
    price int
)
--create index #idx2 on #tbl2(price);

declare @start_id as int
set @start_id=0
 
while @start_id < 100000
    begin
        print @start_id
        insert into #tbl1 values(@start_id, @start_id % 3, @start_id * Rand() * 10)
        insert into #tbl2 values(@start_id, @start_id % 3, Rand() * 1000)
        insert into #tbl2 values(@start_id, @start_id % 3, Rand() * 1000)
        insert into #tbl2 values(@start_id, @start_id % 3, Rand() * 1000)
        set @start_id = @start_id +1
    end

--select * from #tbl1
--select * from #tbl2 where price >= 900
--ここからテスト

/* EXISTS 句でパフォーマンステスト */
print CONVERT(VARCHAR, GETDATE(), 114) 
select * from #tbl1 t1
 where EXISTS (
  select * from #tbl2 t2
	where t1.id= t2.id     --レコードのリンク
	and t2.price >= 900
 )
print CONVERT(VARCHAR, GETDATE(), 114) 


/* IN 句でパフォーマンステスト */
print CONVERT(VARCHAR, GETDATE(), 114) 

select * from #tbl1 t1
 where t1.id IN (
  select t2.id from #tbl2 t2
   where t2.price >= 900
 )

print CONVERT(VARCHAR, GETDATE(), 114) 


/* join 句でパフォーマンステスト */
print CONVERT(VARCHAR, GETDATE(), 114) 

select distinct t1.* from #tbl1 t1
inner join #tbl2 t2
on t1.id=t2.id
where t2.price >= 900

print CONVERT(VARCHAR, GETDATE(), 114) 

/* drop table */
/*
drop table #tbl1
drop table #tbl2
*/

ここでまず、INDEX無のEXISTS,IN,INNER JOINのそれぞれの実行プランを確認してみます。
EXISTS句

EXISTS句-パターン1INDEX無の実行プラン

EXISTS句-パターン1INDEX無の実行プラン


クエリコストがバッチ相対で9%になっています。

IN句

IN句-パターン1INDEX無の実行プラン

IN句-パターン1INDEX無の実行プラン


EXISTS句と同じくクエリコストがバッチ相対で9%になっています。

INNER JOIN句

INNER JOIN句-パターン1INDEX無の実行プラン

INNER JOIN句-パターン1INDEX無の実行プラン


クエリコストがバッチ相対で25%になっています。

実行して試してみます。
ただし一度メモリに読み込まれてしまうと、最適化された状態で動くことになるので、実際のパフォーマンスとはかなり異なります。
もし、少しでも正確に行いたいのなら、テーブルを毎回作り直して、初回で比較する方が良いと思われます。
今回はメモリに展開したうえでのパフォーマンス比較を行っています。各々2回図ります。

参考:ど初回、EXISTS句
開始:07:52:12:613
終了:07:52:14:300
結果:1687ms

—–ここから

初回:EXISTS句
開始:08:01:44:583
終了:08:01:46:287
結果:1704ms

初回:IN句
開始:07:58:20:097
終了:07:58:21:690
結果:1687ms

初回:INNER JOIN句
開始:08:07:10:097
終了:08:07:12:363
結果:2266ms

2回:EXISTS句
開始:08:08:32:600
終了:08:08:33:927
結果:1327ms

2回:IN句
開始:08:05:31:440
終了:08:05:33:160
結果:1720ms

2回:INNER JOIN句
開始:08:03:56:490
終了:08:03:57:973
結果:1483ms

なんとも締まらない結果になってしまいました。
10万件では少なかったかな。。。
とりあえず、次はpriceにIndexを貼ってやってみます。
でも実行プランも変わらなかったので、priceにIndexを貼っても効果ないようです。
どこにどう貼れば効果あるのかな・・・
ちなみに、Indexを貼るのに10秒かかりました。

初回:EXISTS句
開始:08:13:15:660
終了:08:13:17:647
結果:1987ms

初回:IN句
開始:08:15:48:677
終了:08:15:50:520
結果:1843ms

初回:INNER JOIN句
開始:08:14:47:300
終了:08:14:49:130
結果:1830ms

2回:EXISTS句
開始:08:16:37:147
終了:08:16:38:270
結果:1123ms

2回:IN句
開始:08:18:28:660
終了:08:18:29:833
結果:1173ms

2回:INNER JOIN句
開始:08:17:32:973
終了:08:17:34:647
結果:1674ms

Indexを貼っても有効に機能しなかったので結果は同じでしたね。
簡単なテーブルではパフォーマンスに差も出ないようですね。
じっくり検討すれば早くなる可能性もありますが、とりあえず簡易テストの結果、それほどの差は出ないということでした。

以上、簡単なサンプルでの説明でしたが、SQL SERVER EXISTS、NOT EXISTS についてでした。

無償アップグレード後、Windows 10 の再インストール

無償アップグレード後、Windows 10 の再インストール

テーマ通り、「無償アップグレード後、Windows 10 の再インストール」についての備忘録です。

会社のPCの一台が立ち上がらなくなってしまいました。
どうやらHDDがおかしくなってしまったようです。。。(´;ω;`)ウゥゥ
で、システムファイルが壊れただけかもしれないので、他のPCでHDDのファイル修復を掛けたら直るかもしれないのですが、なんとなく無償アップグレード後のWindows 10 の再インストールを試みようかと思ったので、試してみる次第です。

Windows 10 の再インストールできる条件

実際、無償アップグレードなんのトラブルも無かったので、下調べも何もしてないので、少し調べてみました。
「ハードウェア構成を変えていなければ、Windows 10 の再インストールもできる」と言うものでした。
基本的にインストールはできるけど、ライセンス認証ができるかどうかは、ハードウェア構成次第ってことで、このライセンス認証については、昔から変わらないですね。

ただ、Windows 10への無償アップデートにおける認証は新たな手法が取り入れられているそうです。
アップグレードした時点で、元のOSの認証確認だけでなくハードウェア情報もマイクロソフト側へ登録されているそうです。

マザーボードやLANカードやその他のハードウェア情報をライセンス認証情報と共に登録しておき、再インストールされた際にその情報と照らし合したうえで承認できれば自動でライセンス認証される仕組みです。
で、ハードウェア構成を変えた場合は、十分に承認できるライセンス情報が残っていない可能性もあるわけで、その場合は自動でライセンス認証されません。

正規のWindows 10を購入していれば、ライセンスキーも付属してくるため、自動でライセンス認証さなくても、付いてきたライセンスキーでオンラインで承認できるし、もし、オンラインで承認できなくても電話で承認依頼ができますが、無償アップグレードのライセンスキーではそのような依頼ができないようです。

マザーボードを変えたりするとライセンス認証されないので、マザーボードの故障でPCが使えなくなった場合は、Windows 10 を新たに購入する必要が出てきます。マイクロソフトに事前相談したら何か対応をしてくれる可能性もあるかもですが、わかりません。

Windows 10 の再インストール手順

1)MediaCreationToolsのダウンロード
『Windows 10 ダウンロードサイト(マイクロソフト)』

2)MediaCreationToolsでWindows 10 をダウンロード
MediaCreationToolsを起動し、「別のPCのインストール メディアを作成する(USB フラッシュ ドライブ、DVD、またはISO)」を選択して次に進みます。
随時、説明に従って必要なWindows 10のEditionを、目的のメディアにダウンロードします。
大きなファイルなのでそれなりに時間がかかります。

3)再インストール
目的のPCにダウンロードしたWindows 10を使用してクリーンインストールします。
プロダクトキーの入力ページでは「スキップ」ボタンを選択してください。
ハードウェア構成を変えていなければ、オンラインになったときに、自動でライセンス認証もしてもらえます。

※)不運にも自動でライセンス認証出来なかった場合は、Windows 10を新規に購入する必要が有るようです。
「無償アップグレード版 Windows 10」は、正規のWindows 10と異なるものと考えましょう。

以上、無償アップグレード後、Windows 10 の再インストールの備忘録でした。

Let’s Encryptで無料のSSLを取得する

Let’s Encryptで無料のSSLを取得する

最近のGoogle検索は、WebサイトにSSLが掛かっているかを上位表示の条件にしています。
なのでとりあえず会社のWebサイトくらいはSSLを掛けておこうかと思い、先日から掛けています。

ただSSL証明書発行も無料じゃないし、独自SSLサービスを行っているレンタルサーバも有るのですが、私の契約しているレンタルサーバはそんなサービスもない、格安レンタルサーバなので。。。

そこでLet’s Encryptで無料のSSLを取得することにしました。

更新は2回目なのですが、何かと忘れぽいので、手順の備忘録を残しておきます。
私はスタードメインを利用しているので、スタードメインの管理画面から「Let’s Encrypt SSL証明書」を取得します。

たぶん新規も更新もそう変りない手順かと思いますが、とりあえず更新のみを。
先ずはSSL更新画面を表示します。

SSL更新画面を呼び出す

SSL更新画面を呼び出す


1)メニューから「SSLボックス管理」をクリックします
 右側の画面がSSLの取得証明一覧に更新されます。
 新規の場合は、左側メニューにある新規取得をクリックします。
2)一覧の中のSSLを更新するWebサイトの「更新申込」をクリックします
 画面が「Let’s Encrypt SSL証明書 新規取得」に変わります。
 なぜ、新規取得になるかは。。。不明?
SSL更新 DNS認証を行う

SSL更新 DNS認証を行う


3)Web認証かDNS承認かを選択します。
 私は自由度が低いレンタルサーバのため、DNS承認を選択しています。
4)SSL更新をしたWebサイトのDNSのTXTレコードを更新します
 私の場合は、レンタルサーバのDNSを使っているため、レンタルサーバのDNSの_acme-challenge.xxxxx.xx.xxTXTレコードを更新します。
 DNSの更新はすぐに行われても、既に出回っているTXTレコードは以前前のままなので、しばらく時間を置く必要があります。
 私は、あくまで目安ですがDNS TXTレコード確認をして書き換わっているのを確認してから次の作業に進んでいます。
5)「所有者確認」ボタンをクリックします
 確認が行われ、正常に確認されると「証明書を発行する」にボタンが変わります。
6)「証明書を発行する」ボタンをクリックします
 新しく取得したSSL証明書が表示されます。
 取得したSSL証明書は取得証明書一覧からも確認することができます。

以上、簡単な説明でしたが、Let’s Encryptで無料のSSLを取得するでした。
 

HTML5 Canvusにテキスト表示する

Canvusにテキスト表示する

HTML5から実装されているCanvusにテキスト表示する簡単なプログラム書いて試してみました。
やはり、今更ながらなのですが。。。

この簡単に書いたプログランは、
・背景色を時刻で変える
・日時を表示する
だけの簡単なものです。
テストはChromeとEdgeで行いました。Chromeは毎回確実に動作をしたのですが、Edgeは動かなくなることがありました。
何かいけないことをしているのかも。。。よくわかっていないので、公開するものに使う時はEdgeで十分にテストしてください。
可能ならどうしてEdgeで動かなくなることがあるのかコメントで教えてもらえるとありがたいです。よろしくお願いします。

一読してもらえばおおよその内容がわかると思います。
インターバルで1秒ごとに背景色と日時時刻を書き換えているだけのシンプルなプログラムです。
初期状態のcanvusの状態を保持と初期状態のcanvusの状態を復元はこのプログラムの中では意味はありませんが、複雑なプログラムになってくると便利らしいです。
私もピンと来ていません(イニシャライズ関数を作れば良いような。。。)が、学習した本に載っていたので便利なんだろうと思い、使うようにしています。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>test</title>
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
	alert("Canvusテスト");

	var cCanvus = null;
	var cContext = null;

	//$('#canvus1').load(function () {
	window.addEventListener("load",function(){
		// id:canvus1が読み込まれた際に実行したい処理
		cCanvus = document.getElementById("canvus1");
		cContext = cCanvus.getContext("2d");
		setInterval(drawCunvas, 1000);
	});

	function drawCunvas() {
		//cContextをクリア
		cContext.clearRect(0, 0, 300, 250);
		//現在時刻を取得
		var t = new Date();
		//背景の描画
		drawBackGround(t);
		//日時を描画
		drowDateTime(t);
		
	}

	function drawBackGround(t) {
		//初期状態のcanvusの状態を保持
		cContext.save();

		//時刻によって背景色を変える
		var h = t.getHours();
		if (h > 6 && h < 18) {
			cContext.fillStyle = "#aaa";
		} else {
			cContext.fillStyle = "#333";
		}
		//背景を塗りつぶす
		cContext.fillRect(0, 0, 300, 250);

		//初期状態のcanvusの状態を復元
		cContext.restore();
	}

	function drowDateTime(t) {
		//初期状態のcanvusの状態を保持
		cContext.save();

		//日付の文字列を作成
		var tDate = (t.getYear() + 1900).toString() + "年" + (t.getMonth() + 1).toString() + "月" + (t.getDate()).toString() + "日(" + ["日", "月", "火", "水", "木", "金", "土"][t.getDay()] + ")";



		//時刻の文字列を作成
		var tTime = (t.getHours()).toString() + "時" + (t.getMinutes()).toString() + "分" + (t.getSeconds()).toString() + "秒";

		//日時を描画
		cContext.font = "18px";
		cContext.fillText(tDate, 100, 210);
		cContext.fillText(tTime, 100, 230);

		//初期状態のcanvusの状態を復元
		cContext.restore();
	}

});
</script>
<style type="text/css">

</style>
</head>
<body>


<form>
 <div>
 Canvusテスト
 </div>
 <fieldset>
  <LEGEND></LEGEND>
	<canvas id="canvus1" width="300" height="250"></canvas>
 </fieldset>

 <p><button type='submit'>送信</button></p>
</form>
</body>
</html>

以上、「HTML5 Canvusにテキスト表示する」の簡単なサンプルテストでした。