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

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 についてでした。

IX Web Hosting ハッキングされた!

IX Web Hosting ハッキング

IX Web Hosting を使い始めて8か月目、ハッキングされたことに気が付きました。
見たことのないFileが入り込んでいました。

FTP経由で入り込んだと思われますが、FTPは複雑なパスワードにしているので、簡単に解析出来るとも思えません。
何もないほぼテストサイトに時間をかけて侵入する意味などないので愉快犯だと思います。

とりあえずFTPのパスワードを変更して、ハッキングされたファイルをバックアップから戻しましたが、どこから入ってこられたのか不明です。
テストサイトなので、持ち出されて困る情報はありませんが、気持ち悪いです。

ちなみに、IX Web Hosting の管理サイトには、ぱっと見ログを取るような仕組みは無さそうです。
IX Web Hosting の運営に調査を依頼することになるのでしょうが、英語だし、パスワード管理が悪い!ってことになりそうなので、今回は調査を見送りました。

みなさんもパスワード管理をしっかりしましょうね。
って、内部流出もあるので、杜撰な管理しかしていない運営や会社を利用しない方が良いかも。。。

とりあえず、こまめにファイルチェックの日々が続きそうです。。。( ノД`)シクシク…

無償アップグレード後、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にテキスト表示する」の簡単なサンプルテストでした。

HTML5 数値を選択する入力フィールド

数値を選択する入力フィールド

HTML5から実装されているHTML5 数値を選択する入力フィールドを試してみました。
やはり、今更ながらなのですが。。。

もともと必要ならリストやスライダー等とjavascriptを使って自前で組み込んでいたのですが、どの程度使えるのかと思って。
簡単に数値選択が可能なので、アンケート等で使用するならこれで十分な気がします。
下に試したHTMLを貼っておくので試してみては如何でしょうか?
ちなみに、ブラウザによって微妙な違いが出るかもしれませんので、そのあたりのチェックもした方が良いと思われます。

下のHTMLはtype=’renge’を使って単純な数値を選択する入力フィールド2つを試しています。
バーを移動させるごとに数値を取得して表示しています。
送信ボタンをクリックすると送信されてクリアされます。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;" />
<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("テスト開始!数値を選択する入力フィールドのチェックHTMLです");

  $("#range1").change(function() {
    //値が変更されたときの処理
    $("#disp1").val($("#range1").val());
  });

  $("#range2").change(function() {
    //値が変更されたときの処理
    $("#disp2").val($("#range2").val());
  });
});
</script>
<style type="text/css">

</style>
</head>
<body>

<form>
 <div>
 テスト
 </div>
 <fieldset>
  <LEGEND></LEGEND>
  <label>デフォルトの場合、min属性の初期値は0、max属性の初期値は100となります。 また、step属性の初期値は1となります</label>
 <p><label>少ない<input type='range' id='range1'>多い</label><input type='text' id='disp1'></p>

 <label></label>
 </fieldset>

 <fieldset>
  <LEGEND></LEGEND>
  <label>min属性の初期値は1、max属性の初期値は5となります。 また、step属性1とした場合</label>
 <p><label>悪い<input type='range' id='range2' min='1' max='5' step='1'>良い</label><input type='text' id='disp2'></p>

 <label></label>
 </fieldset>

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

</body>
</html>

以上、「HTML5 数値を選択する入力フィールド」の簡単なチェックでした。

HTML5 数値の入力フィールド バリデーションチェック

HTML5 数値の入力フィールド バリデーションチェック

HTML5から実装されているHTML5 数値の入力フィールドのバリデーションチェックを試してみました。
今更ながらなのですが。。。

もともと必要ならjavascriptを使って自前で組み込んでいたのですが、どの程度使えるのかと思って。
簡単な入力チェックならこれで十分な気がします。
下に試したHTMLを貼っておくので試してみては如何でしょうか?
ちなみに、ブラウザによって微妙な違いが出るかもしれませんので、そのあたりのチェックもした方が良いと思われます。

下のHTMLは単純な数値の入力フィールド、小数点の数値の入力フィールド、範囲を指定した数値の入力フィールドの3つを試しています。
送信ボタンをクリックするとバリデーションチェックが行われ、問題が有ればメッセージが表示されます。
問題がなければ送信されてクリアされます。

なので、入力中にチェックをしたいのならこのバリデーションチェックを使うことができません。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;" />
<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("テスト開始!入力フィールドに数値以外が入るとバリデーションチェックが入ります。");
});
</script>
<style type="text/css">

</style>
</head>
<body>

<form>
 <div>
 テスト
 </div>
 <fieldset>
  <LEGEND>数値の入力フィールド</LEGEND>
  <label></label>
 <p><label><input type='number' name='number'></label></p>

 <label></label>
 </fieldset>

 <fieldset>
  <LEGEND>小数点の数値の入力フィールド</LEGEND>
  <label></label>
 <p><label><input type='number' name='number1' step='0.1'></label></p>

 <label></label>
 </fieldset>

 <fieldset>
  <LEGEND>範囲を指定した数値の入力フィールド</LEGEND>
  <label>1~99まで</label>
 <p><label><input type='number' name='number1' min='1' max='99'></label></p>

 <label></label>
 </fieldset>

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

</body>
</html>

以上、「HTML5 数値の入力フィールド バリデーションチェック」の簡単なチェックでした。

SQL SERVER 日付の加算、減算

SQL SERVER

日付の加算、減算

SQL Serverは、DATEADD関数を使って日付型の値に日時を加算、減算する事ができます。

構文:DATEADD(element, value, target)

elementには日付要素を記述します。
日付要素は以下のようなものがあります。
year(yy or yyyy) : 年
quarter(qq or q) : 四半期
month(mm or m) : 月
dayofyear(dy or y) : 年始からの日数
day(dd, d) : 日
week(wk, w) : 週
weekday(dw) : 曜日
hour(hh) : 時
minute(mi or n) : 分
second(ss) : 秒
millisecond(ms, s) : ミリ秒

valueには加算、減算した値を設定します。
targetには、基準となる日付型の値を設定します。

日付の加算

日の加算をしたい場合は、elementに「day」、valueに「加算したい日数」、targetに基準日を設定します。

例えば、現在から5日後の日付が欲しい場合は、
DATEADD(day, 5, getdate())
で取得できます。

例えば、現在から12時間後の日付が欲しい場合は、
DATEADD(hour, 12, getdate())
で取得できます。

日付の減算

日の減算をしたい場合は、elementに「day」、valueに「減算したい日数」、targetに基準日を設定します。
減算したい日数は、マイナスで指定します。
1日前なら-1、2日前なら-2

例えば、現在から5日前の日付が欲しい場合は、
DATEADD(day, -5, getdate())
で取得できます。

例えば、現在から12時間前の日付が欲しい場合は、
DATEADD(hour, -12, getdate())
で取得できます。

上の説明でほぼ理解できたと思いますが、一応例を載せておきます。

declare @d datetime
declare @d2 datetime
declare @d3 datetime
declare @d4 datetime

print '現在時刻をセット'
set @d=getdate()
print @d
print ''

print '10時間後を指定'
set @d2=dateadd(hour,10,@d)
print @d2
print ''

print '10日時間を指定'
set @d2=dateadd(hour,-10,@d)
print @d2
print ''

print '10日後を指定'
set @d2=dateadd(day,10,@d)
print @d2
print ''

print '10日前を指定'
set @d2=dateadd(day,-10,@d)
print @d2
print ''

print '簡易な計算方法----------'
print '10日後を指定'
set @d3=@d+10
print @d3
print ''

print '10日前を指定'
set @d3=@d-10
print @d3
print ''

print '簡易な計算方法で少数点を使うと----------'
print '0.001日後を指定'
set @d4=@d+0.001
print @d4
print @d4-@d
print convert(nvarchar(36), @d4-@d,21)
declare @dec decimal(11,6)
set @dec=3600*24/1000
print @dec/60

上の例の中に簡易な計算方法も載せておきました。
基本は日単位の計算なので単純な加算、減算なら+10とか-10で計算してくれます。
また、12時間とか6時間という切りの良い時間なら、0.5や0.25と言った指定でできます。

この辺りは好みもありますが、ちゃんとDATEADDを使った方が面倒にならない気もします。
以上、SQL SERVER 日付の加算、減算の開発備忘録でした。