SELECT GETDATE()
上記クエリを実行すると、「2015-01-05 23:00:05」のように日付と時刻が返ってきます。
日付だけを取得したい場合にはどうしたらいいのでしょうか。
SQL Server 2008 以降であれば、つぎのクエリで取得できます。
SELECT CONVERT(date, getdate())
このクエリを実行すると、「2015-01-05」を取得することができます。
SELECT GETDATE()
上記クエリを実行すると、「2015-01-05 23:00:05」のように日付と時刻が返ってきます。
日付だけを取得したい場合にはどうしたらいいのでしょうか。
SQL Server 2008 以降であれば、つぎのクエリで取得できます。
SELECT CONVERT(date, getdate())
このクエリを実行すると、「2015-01-05」を取得することができます。
一つのSQLクエリで、複数の行を追加するには、カンマでつなげればOKです。
SQL Server 2008では、次のようなクエリでOKです。
INSERT INTO Table ( C1, C2 ) VALUES ( Value1, Value2 ), ( Value1, Value2 )
一つのクエリで追加できる最大行は、1000行です。
ちなみに、SQL Server 2005では動作しないので、SQL Server 2005では次のような方法をとることになります。
INSERT INTO dbo.MyTable (C1, C2)
SELECT Value1, Value2
UNION ALL
SELECT Value1, Value2
UNION ALL
SELECT Value1, Value2
次のようなクエリを書いたら暗黙的菜型変換に失敗しました。
Response.Redirect(response.ResponseUri.ToString());
エラーメッセージ
Cannot convert type ‘System.Uri’ to ‘string’
暗黙的な型変換ではダメ、次のような「(cast)response.ResponseUri」型変換もダメで、おとなしく「Tostring」を使用すればOK
Response.Redirect(response.ResponseUri.ToString());
RestSharpのサンプルコードに従って書いたらエラーが出た。
RestResponse response = client.Execute(request);
エラー文面
Cannot implicitly convert type ‘IRestResponse’ to ‘RestResponse’. An explicit conversion exists (are you missing a cast?)
Dropbox API and RestSharp for a C# developerに対処方法が記載されていました。
次のように書き換えて対応しました。
var response = client.Execute(request);
次のようなDateTime型のデータがあります。
Examle == 2015-01-09 15:19:00 2015-01-09 14:10:00
Timeだけを抽出して、次のような結果を取得する方法について説明します。
Examle == 2015-01-09 15:19:00 2015-01-09 14:10:00
select cast(Example as time) [time] from table
select convert(char(5), Example, 108) [time] from table
ASP.NET Web APIは、モバイルデバイス、ブラウザ、クライアントアプリなどで、HTTPサービスを簡単に作ることができるフレームワーク。ASP.NET Web APIは、.NET Framework上で、RESTfulアプリケーションを構築するためのプラットフォーム。
Nugetで提供されている。
Install-Package Microsoft.AspNet.WebApi.Client
.NET で、POSTやGETなどのRESTful通信をしたいときに使うと手軽で実現可能。
こんな感じでかけるので素のPOST処理を書くのに比べると段違い。
using (var client = new HttpClient()) { client.BaseAddress = new Uri(baseUrl); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var accesstoken = new accessToken(clientId, clientSecret, code); HttpResponseMessage response = await client.PostAsJsonAsync("/api/v2/access_tokens", accesstoken); if (response.IsSuccessStatusCode) { Uri gizmoUrl = response.Headers.Location; } }
Microsoft Intuneには、SA権(ソフトウェアアシュアランス)ついていて、素晴らしい!のはずだったのだが、ひっそりと提供が終了していた(´・ω・`)
http://www.microsoft.com/ja-jp/server-cloud/products/microsoft-intune/buy.aspx
- Windows ソフトウェア アシュアランス付きライセンスの提供終了のお知らせ –
これまでマイクロソフト オンライン サブスクリプション契約で販売しておりました Windows ソフトウェア アシュアランス付き Microsoft Intune のライセンスの提供を、2014 年 12 月 31 日をもって終了いたします。
2014 年 12 月 31 日以前に同ライセンスを購入されたお客様は、更新により既存のライセンスをそのままご利用いただけますが、2015 年 1 月 1 日以降、ライセンス数を増加することはできません。
社内ツールとして、Chromeの拡張機能(Extension)を配布しているが、セキュリティ強化を目的としたChromeの仕様変更により、エラーでインストールできなくなった。
従来はポリシー(ExtensionInstallWhitelist や ExtensionInstallSources)で対応していたのだけど、Chrome 39辺りでもMac用Chromeで仕様変更あったみたいで、インストールできなくなった。それの対処方法。
次のような、「profile.mobileconfig」ファイルを用意する。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadIdentifier</key>
<string>com.yourname.Angrybird</string>
<key>PayloadRemovalDisallowed</key>
<false />
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>bde4dcb5-d4bf-4943-b992-c30f82eb1468</string>
<key>PayloadOrganization</key>
<string>com.gloops</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadDisplayName</key>
<string>com.gloops</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadIdentifier</key>
<string>com.yourname.Angrybird.f13e3b90-6187-0132-2314-685b357e505d</string>
<key>PayloadUUID</key>
<string>f13e3b90-6187-0132-2314-685b357e505d</string>
<key>PayloadEnabled</key>
<true />
<key>PayloadDisplayName</key>
<string>Google Chrome</string>
<key>PayloadContent</key>
<dict>
<key>com.google.Chrome</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>ExtensionInstallWhitelist</key>
<array>
<string>epkhkajflhigkpbcfcolaocpcgfikmah</string>
</array>
<key>ExtensionInstallSources</key>
<array>
<string>https://auth.clayapp.jp/*</string>
</array>
</dict>
</dict>
</array>
</dict>
</dict>
</dict>
</array>
</dict>
</plist>
このファイルを、sudo /usr/bin/profiles -I -F ./profile.mobileconfig でインストールしてあげれば、Chromeにポリシーが読み込まれて幸せになれる。
SQL Server Management Studio (SSMS)で、拡張イベントを表示すると、最初の1000000行しか表示してくれない。百万行ですよ。
これ仕様で表示行数を増やすことができない。
なので、タイムレンジやイベントタイプなどのフィルターを設定してあげるしかない。
Cisco ANyConnectの動作が不安定だったので、アンインストールして再インストール!ってすると、まれに、Interprocess Communication Depot Errorが出てしまい、インストール出来ないことがあります。
The vpn client agent was unable to create the interprocess communication depot.
Embulkの名前の由来が、Twitterで流れていたので雑学としてメモしておきます。
@repeatedly 曰く「今開発中のバルクロードツール,一番の問題は名前だと思う.社内のリポジトリの名前はアレ過ぎてダメ」
@kazuho 曰く「@repeatedly embulkにしましょう #embarkにかけてるつもり」
@frsyuki 曰く「@kazuho ほう! embulkいいですね…ちょうど別の名前を考えつつあったところなのですが、揺らぐ…」
@frsyuki 曰く「新しいものは名前に困る。fluentdも最初は「syslogのjson使えるようになったやつ」だったような。」
embarkにかけてembulk
SQL Server 2012以前のSQL Serverでは、リンクサーバーはログインにdd_ddladminまたはdb_owner、sysadminを権限を使用したほうが、良い実行計画の遂行が行われます。
上の図のような状態で実験をしてみます。
testリンクサーバーとは、「db_datareader」権限のユーザーを使用。
test1リンクサーバーとは、「db_datareader」と「db_ddladmin」権限のユーザーを使用。
次のクエリを実行する。
select * from [TEST1].[AdventureWorks].[Sales].[SalesOrderDetail]
a INNER JOIN dbo.[SalesOrderHeaderSalesReason] b
ON a.SalesOrderID = b.SalesOrderID
where b.SalesOrderID between 75017 and 75111
select * from [TEST].[AdventureWorks].[Sales].[SalesOrderDetail]
a INNER JOIN dbo.[SalesOrderHeaderSalesReason] b
ON a.SalesOrderID = b.SalesOrderID
where b.SalesOrderID between 75017 and 75111
こんな感じで明らかに実行計画上に差異が発生します。
MSDNブログで投稿されていた「JSON support in SQL Server 2016」が元ネタ。
SQL ServerでのJSONサポートは、Microsoft connect siteで、1000以上の投票が集まるリクエストが多いもののひとつです。マイクロソフトは、SQL Server 2016で、デフォルト機能でJSONサポートをすることを発表しました。
まず最初に、nativeのJSONサポートは、nativeのJSONデータ型を提供するわけではありません。SQL Server 2016では、JSONは、NVARCHARデータ型で表現される予定です。
最初の機能提供は、SQL Server 2016 CTP2で提供されており、「FOR JSON」を使用してJSON形式で結果を取得できるようになっています。
SELECT column, expression, column as alias FROM table1, table2, table3 FOR JSON [AUTO | PATH]
T-SQLクエリの最後に、「FOR JSON」を追加すると、JSONテキスト形式の結果をクライアントに返します。各行は全て、JSONオブジェクトの一部として整形され、セルの値はJSONオブジェクトの値として生成されます。
OPENJSONは、JSONテキストを探すテーブル値機能(TVF)です。
SELECT Number, Customer, Date, Quantity FROM OPENJSON (@JSalestOrderDetails, '$.OrdersArray') WITH ( Number varchar(200), Date datetime, Customer varchar(200), Quantity int ) AS OrdersArray
@JSalesOrderDetailsは、次のような例のOrdersArrayプロパティでJSONオブジェクトの配列を含むテキストです。
‘{"OrdersArray": [
{"Number":1, "Date": "8/10/2012", "Customer": "Adventure works", "Quantity": 1200},{"Number":4, "Date": "5/11/2012", "Customer": "Adventure works", "Quantity": 100},
{"Number":6, "Date": "1/3/2012", "Customer": "Adventure works", "Quantity": 250},
{"Number":8, "Date": "12/7/2012", "Customer": "Adventure works", "Quantity": 2200}
]}’
OPENJSONは、プロパティで配列を見つけ、JSONオブジェクトごとに行を返します。結果セットには、4列含まれ、定義は、「WITH」で指定します。OPENJSONは、Number、Date、Customer、Quantityプロパティを見つけ、結果セットのカラムに値を変換します。デフォルトでは、プロパティが見つからない場合はNULLを返します。
SELECT t.Id, t.OrderNumber, t.OrderDate, JSON_VALUE(t.JOrderDetails, '$.Order.ShipDate'), JSON_QUERY(t.JOrderDetails, '$.Order') FROM SalesOrderRecord AS t WHERE ISJSON(t.JOrderDetails) > 0 AND JSON_VALUE(t.JOrderDetails, '$.Order.ProductType') = 'TV'
今のところJSON用のカスタムインデックスを追加する予定はありません。
JSONはプレーンなテキストで、既存のB-Treeやフルテキスト検索インデックスを使用できます。
たとえば次のように、JSON_VALUE関数を使用して、計算列を作成し、その列に標準のインデックスを作成します。
CREATE TABLE SalesOrderRecord ( Id int PRIMARY KEY IDENTITY, OrderNumber NVARCHAR(25) NOT NULL, OrderDate DATETIME NOT NULL, JOrderDetails NVARCHAR(4000), Quantity AS CAST(JSON_VALUE(JOrderDetails, '$.Order.Qty') AS int), Price AS JSON_VALUE(JOrderDetails, '$.Order.Price'), ) GO CREATE INDEX idxJson ON SalesOrderRecord(Quantity) INCLUDE (Price);
Google Apps Admin SDKのDirectory APIを使用して、Userを追加登録しようとしたのだけど、次のエラーが出て追加できなかった。
Scopeで、「DirectoryService.Scope.AdminDirectoryUser」を指定しているのにどうしても、権限不足とのエラーが出てしまう。
Google.GoogleApiException はユーザー コードによってハンドルされませんでした。
HResult=-2146233088
Message=Google.Apis.Requests.RequestError
Not Authorized to access this resource/api [403]
Errors [
Message[Not Authorized to access this resource/api] Location[ – ] Reason[forbidden] Domain[global]
]
Source=Google.Apis
ServiceName=admin
StackTrace:
原因は、APIアクセスに使用しているアカウントに権限が無かったから。
具体的には、ドメインの管理コンソールを開いて、管理者の役割から該当アカウントにUser作成権を付与してあげないといけない。
当初は参照しか必要なかったので参照権しか付与していなかった。
User作成権をここで付与してあげないと、API側でいくら付与しようとしたり、Scopeを定義しても権限不足は解消できないのであった。2時間ぐらい悩んだ。。。
Google Appsの管理のために、Admin Directory APIを触っています。
Google Appsのアカウントをどの組織に作成するかを選ぶために、組織一覧を取得するためにdirectory.orgunits.listを使用します。
使用方法を確認するために、GoogleのAPIs Explorerにアクセスして、directory.orgunits.listを開きました。
あれ?customeridが必須になっているのですが…ここ、何の値を入力するのでしょうか?
ドメイン名?個人アカウント?
どれも違いました。
If you are an account administrator retrieving all sub-organization units, use my_customer.
うん?いや、だから…my_customerに何を代入するんだって!!!
っと困り果てて試行錯誤すること10分。
よーやく理解しました。
customeridにいれる値は「my_customer」なんだと。ここに何か別の文字列を代入するとかではなく!そのまま文字列を入れるのだと。
はい!めでたく、これで結果を取得することができました。ちゃんちゃん。
わかるかーーー!!!
"access_denied", Description:"Requested client not authorized.", Uri:
SQL Server 2016のデータベースエンジンの新機能の1つに「SQL Server Managed Backup to Azure(単にManaged Backupと表記されることもある)」があります。
Microsoft Azure Blobストレージに自動的にSQL Serverのバックアップをとったり、管理するための機能です。
バックアップタイミングは次の2パターンを選ぶことができます。
Microsoft Azure Blobストレージにバックアップファイルを保存する期間を設定できます。
これまでは、時間指定のバックアップを設定するか、カスタムコードを書かないと自動バックアップを設定することができなかったのです。
しかし、SQL Server Managed Backup to Windows Azureを使用すると、バックアップファイルの保持期間と、保存場所を指定すれば自動的にバックアップされます。オプションでスケジュールを指定することもできますが不要です。
次の範囲で、Managed Backupを設定できます。
インスタンスレベルで定義をしておくと、新しいデータベースを作成したときにも自動的にバックアップされます。
次のサービス、アカウント、認証情報が必要です。
項目 | SQL Server 2014 | SQL Server 2016 |
名前空間 | smart_admin | managed_backup |
ストアド | sp_set_db_backUP sp_set_instance_backup | sp_backup_config_basic sp_backup_config_advance |
セキュリティ | ストレージアカウント アクセスキー | 共有アクセス署名 |
ストレージ | ページBlob | ブロックBlob |
SQL Server 2016では次のような機能特徴がある
具体的な手順はドキュメントに記載されているので、簡単な流れのみ記載。
Azure PowerShellを使用して、バックアップファイルを格納するコンテナーのSASを取得します。以下の例は、既存のコンテナーのSASを取得する例。
Get-AzurePublishSettingsFile
Import-AzurePublishSettingsFile
Select-AzureSubscription
$context = New-AzureStorageContext -StorageAccountName ***atoya -StorageAccountKey (Get-AzureStorageKey -Storage
New-AzureStorageContainerSASToken -Name pub -Permission rwdl -FullUri -Context $context
次に、SQL証明書を作成します。
CREATE CREDENTIAL [https://***atoya.blob.core.windows.net/pub]
WITH IDENTITY = ‘Shared Access Signature’,
SECRET = ‘sv=2014-02-14&sr=c&sig=********wUKKjd2d8%3D&se=2015-07-08T01%3A55%3A03Z&sp=rwdl’
Managed Backupを設定します。
Use msdb;
GO
EXEC msdb.managed_backup.sp_backup_config_basic
@enable_backup = 1,
@database_name = ‘test’,
@container_url = ‘https://y****a.blob.core.windows.net/pub’,
@retention_days = 30
GO
ストアドプロシージャーを設定すると、次のように設定しましたと出力されます。
裏側では、フルバックアップが実行されます。
Database backed up. Database: test, creation date(time): 2015/05/28(23:11:16), pages dumped: 369, first LSN: 36:376:37, last LSN: 36:395:1, number of dump devices: 1, device information: (FILE=1, TYPE=URL: {‘https://*****.blob.core.windows.net/pub/test_9806c8082c754fdcbca50ae99e2b1763_20150708100900+09.bak’}). This is an informational message only. No user action is required.
SQL Server Agentサービスを使用すると書いてあるので、てっきりジョブ登録されるのかと思ったのですが、ジョブには登録されていません。
SQLデータベースメールを設定します。
SQL Server Agentメールの設定をします。
監視を追加します。
EXEC msdb.managed_backup.sp_set_parameter
@parameter_name = ‘SSMBackup2WANotificationEmailIds’,
@parameter_value = ‘<t.yam***ya@***ops.com>’
メール通知はこんな感じのが届きます。
バックアップ状況を確認します。
SELECT *
FROM managed_backup.fn_available_backups (‘test’)
取得できる情報は次のようなもの。
backup_path
backup_type
expiration_date
database_guid
first_lsn
last_lsn
backup_start_date
backup_finish_date
machine_name
last_recovery_fork_id
first_recovery_fork_id
fork_point_lsn
availability_group_guid
System.DirectoryServices.AccountManagement を使用して、Active Directoryにユーザーを追加する処理をしていました。
using (var principalContext = new PrincipalContext(ContextType.Domain, host, ou, AdUser, AdPassword)) { using (var userprincipal = new UserPrincipalGloops(principalContext)) { if (!string.IsNullOrEmpty(lastName)) { userprincipal.GivenName = familiyName; } if (!string.IsNullOrEmpty(familiyName)) { userprincipal.Surname = familiyName; } if (!string.IsNullOrEmpty(roma)) { userprincipal.Name = roma; } if (!string.IsNullOrEmpty(familiyName) && !string.IsNullOrEmpty(lastName)) { userprincipal.DisplayName = String.Format("{0} {1}", familiyName, lastName); } if (!string.IsNullOrEmpty(mail)) { userprincipal.EmailAddress = mail; } if (!string.IsNullOrEmpty(employeeNumber)) { userprincipal.EmployeeNumber = employeeNumber; } if (!string.IsNullOrEmpty(idm)) { userprincipal.Description = idm; } if (!string.IsNullOrEmpty(idm)) { userprincipal.SamAccountName = account; } userprincipal.SetPassword(password); userprincipal.Enabled = true; userprincipal.PasswordNeverExpires = true; userprincipal.UserCannotChangePassword = true; try { userprincipal.Save(); } catch (Exception ex) { Logger.Warn("[Create Ad Account] " + ex.Message, ex); return string.Format("NoCreate:{0}",ex.Message); } } }
userprincipa.save()で、例外が発生して、「サーバーがプロセスを実行しようとしません。」と言われちゃいます。(いやいや、実行しろよ!と突っ込みたくなったり)
今回、employee numberに情報を格納するために、プリンシパルの拡張をしていました。
MSDNのサンプルでは、プリンシパルの拡張の冒頭が次のようになっていました。
なので、あまり深く考えずにコピペしたのが運の尽き。
[DirectoryRdnPrefix("CN")] [DirectoryObjectClass("inetOrgPerson")] public class InetOrgPerson : UserPrincipal {
「DirectoryObjectClass」が拡張するクラス名を入れておけば良さそうに見えます。実際、それでも既存ユーザーの更新では問題なく動作するように見えます。
しかし、ユーザーの新規作成時には動作しません。
userを指定すると、例外が発生せずにユーザーを新規作成できるようになりました。
[DirectoryRdnPrefix("CN")] [DirectoryObjectClass("user")] public class UserPrincipalGloops: UserPrincipal {
2時間ぐらいはまった…。
System.DirectoryServices.AccountManagement を使用して、Active Directoryにユーザーを新規作成する処理をしていました。
指定したパスにユーザーを作成したい場合は、PrincipalContextをインスタンス化する際に引数を渡してあげればOKでした。
例えば、「OU=employee,OU=Users,DC=domain,DC=sqlazure,DC=jp」にユーザーを追加したい場合は、次のように書けばいい。
var ou = "OU=employee,OU=Users,DC=domain,DC=sqlazure,DC=jp" var principalContext = new PrincipalContext(ContextType.Domain, hostname, ou, AdUser, AdPassword) var userprincipal = new UserPrincipalGloops(principalContext) . . . userprincipal.Save();
System.Net.HttpにあるHttpClientのBaseAddressの使い方がわからなかったので調べてみた。
HttpClientの使用例として、次のサンプルのようにGetAsyncなどの直接URLを記述する例をよく見ます。
using System.Net.Http; var httpClient = new HttpClient(); var response = await httpClient.GetAsync("http://requestb.in/10v5oew1");
一方で、インテリセンスを見てると、BaseAddressなんてプロパティがあります。
どうやって使い分けるのかがわからなかったので調べてみました。
using System.Net.Http; var httpClient = new HttpClient(); httpClient.BaseAddress = new Uri("http://requestb.in/10v5oew1/"); // こいつは何もの?
調べるのに使用したのは、次のコード。
var baseUri = ""; var getUri = ""; var httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(baseUri); var response = await httpClient.GetAsync(getUri);
「baseUri」と「getUri」にいろんなパターンを当てはめて動作を調べてみました。
「getUri」にフルパスを指定した場合は、「baseUri」にどのようなUriを指定していも、「getUri」で指定したUriにリクエストをする。上書きをする動き。
「baseUri」が「http: //yahoo.co.jp」で、「getUri」が「http: //google.com」と、完全に異なるドメインを指定したとしても、「getUri」の指定が優先される。
「baseUri」の終わりがスラッシュ(「http: //yahoo.co.jp/foo/」)で、「getUri」の始まりがスラッシュでない文字列(「hoge/foo?bar=1」みたいなの)を指定した場合、単純に文字列結合したUrl(「http: //yahoo.co.jp/foo/hoge/foo?bar=1」)にリクエストする。
それ以外のパターンでは、「baseUri」のホストドメイン+「getUri」が結合されたUriにリクエストされる。
HttpClientのBaseAddressを有効活用したいのなら、
- BaseAddressは、スラッシュで終わる
- GetAsyncなどのメソッドでは、スラッシュではじめない
ことが重要であることがわかりました。