トップ回答者
Varbinary(max)のキャストは必要ですか

質問
回答
-
何を気にされているのかよく理解できないのですが、"同様の" キャストは必要ないと思いますよ。
コード ブロック/* varchar の場合 */
declare @string as varchar(max)-- CAST したとき
set @string = replicate(cast('1234567890' as varchar(max)),3000)
PRINT len(@string) -- 10x3000-- CAST しないとき
set @string = replicate('1234567890',3000)
PRINT len(@string) -- 10x3000/* varbinary の場合 */
DECLARE @bin AS varbinary(max)
DECLARE @counter AS int
DECLARE @bin2 AS varbinary(4)-- CAST しないとき
SET @counter = 1
SET @bin = 0xFFFFFFF -- 4 bytes
SET @bin2 = 0xFFFFFFFF -- 4 bytes
WHILE @counter < 10000
BEGIN
SET @bin = @bin + @bin2
SET @counter = @counter + 1
ENDPRINT DATALENGTH(@bin) -- 4x10000
-- CAST したとき
SET @counter = 1
SET @bin = 0xFFFFFFF -- 4 bytes
SET @bin2 = 0xFFFFFFFF -- 4 bytes
WHILE @counter < 10000
BEGIN
SET @bin = @bin + CAST(@bin2 AS varbinary(max))
SET @counter = @counter + 1
ENDPRINT DATALENGTH(@bin) -- 4x10000
結果
30000
8000 <<<<<<<<<<
40000
40000
すべての返信
-
何を気にされているのかよく理解できないのですが、"同様の" キャストは必要ないと思いますよ。
コード ブロック/* varchar の場合 */
declare @string as varchar(max)-- CAST したとき
set @string = replicate(cast('1234567890' as varchar(max)),3000)
PRINT len(@string) -- 10x3000-- CAST しないとき
set @string = replicate('1234567890',3000)
PRINT len(@string) -- 10x3000/* varbinary の場合 */
DECLARE @bin AS varbinary(max)
DECLARE @counter AS int
DECLARE @bin2 AS varbinary(4)-- CAST しないとき
SET @counter = 1
SET @bin = 0xFFFFFFF -- 4 bytes
SET @bin2 = 0xFFFFFFFF -- 4 bytes
WHILE @counter < 10000
BEGIN
SET @bin = @bin + @bin2
SET @counter = @counter + 1
ENDPRINT DATALENGTH(@bin) -- 4x10000
-- CAST したとき
SET @counter = 1
SET @bin = 0xFFFFFFF -- 4 bytes
SET @bin2 = 0xFFFFFFFF -- 4 bytes
WHILE @counter < 10000
BEGIN
SET @bin = @bin + CAST(@bin2 AS varbinary(max))
SET @counter = @counter + 1
ENDPRINT DATALENGTH(@bin) -- 4x10000
結果
30000
8000 <<<<<<<<<<
40000
40000 -
AXShimizu さんからの引用 ファイルをバイナリ化してDBに格納しようとしているのですが、
そのSQLに明示的なキャストを入れるべきか検討しています。
(都合上できれば入れたくないので・・・)
ファイルのバイナリ化をどうやっているかによりますよ。大きなファイルをバイナリ化して DB に入れてみて、そのバイト長を DATALENGTH でチェックしてみたらすぐわかるのではないですか?
AXShimizu さんからの引用 Varchar(max)は必要ですが、Varbinary(max)は不要ということですか?
ちなみにその理由をご存知であればお教えいただけますでしょうか。
理由ですか・・・varchar でキャストが必要な理由は、varchar(max) の変数に '1234567890' を連結すると '1234567890' は varchar(8000) に暗黙的に型変換されて 8000 文字を超えるとそれ以上入らなくなるからです。varbinary は私が挙げた例のやり方では varbinary(max) まで明示的なキャストなしに連結できました。
私が思うに、先日こちらで議論されていたケースとは関係ないんじゃないですか?
-
AXShimizu さんからの引用 DBの型としてはvarchar(max)で用意してあるのに、なぜ明示的にcastしないと8000byteで切られて
しまうのか?ということです。
DB の型っていうのはテーブルのフィールドの型のことを言っているんだと思いますけど、別に varchar(max) の変数などを varchar(max) のフィールドに格納するためにはキャストは必要ありませんよ。char -> varchar の暗黙的な型変換が varchar(max) ではなく varchar(8000) になるだけです。私個人の意見としては仕様として不親切だと思いますけどね。
AXShimizu さんからの引用 そのような仕様であれば納得するのですが、varcharで必要なら、同じようにvarbinaryでも必要なのでは、と思うのです。
同じようには必要ないと言っているではありませんか。もうひとつ例を示します。
コード ブロック/* varbinary の場合 */
DECLARE @bin AS varbinary(max)
DECLARE @counter AS int
DECLARE @bin2 AS binary(4)
-- CAST しないときSET @counter = 1
SET @bin = 0xFFFFFFF -- 4 bytes
SET @bin2 = 0xFFFFFFFF -- 4 bytesWHILE @counter < 10000
BEGIN
SET @bin = @bin + @bin2
SET @counter = @counter + 1
ENDPRINT DATALENGTH(@bin) -- 4x10000
-- CAST したとき
SET @counter = 1
SET @bin = 0xFFFFFFF -- 4 bytes
SET @bin2 = 0xFFFFFFFF -- 4 bytes
WHILE @counter < 10000
BEGIN
SET @bin = @bin + CAST(@bin2 AS varbinary(max))
SET @counter = @counter + 1
ENDPRINT DATALENGTH(@bin) -- 4x10000
結果
40000
40000 -
単純に AXShimizu さんが何をしようとしているかわからないから明言を保留しているだけです。例えばどこかから入手してきたライブラリを使っていて、それが内部的に varbinary(8000) で処理をしているようであればそれを書き直したり自前で作る必要がありますよね。もしくは Windows アプリケーションからファイルを参照してそれを DB に格納している時、経由している変数のキャパシティがどこか一箇所でも入力となるファイルの容量より小さかったら切り捨てられるかエラーになりますよね。IIS6.0 上の Web アプリケーションから POST しようとしているなら、IIS6.0 には一括でポストできる容量に制限があるので分割してバイナリ データを転送しないといけないですよね。私は残念ながら AXShimizu さんがこれからやろうとしているすべてを知っているわけではないのですが、少なくとも varchar(max) について語られていたスレッドの文脈で聞いているのであれば、必要ないということです。
当該のスレッドでも、スクリプトをやり取りして問題の箇所を見つけていたことを思い出していただきたいです。結局質問者が「ここは見せなくてもいいだろう」と提示していなかったところに問題がありました。