2

どういうわけか次のようなストアドプロシージャがあります

create SP_justest
(@datefrom as smalldatetime,
@dateto as smalldatetime,
@rank as varchar(1),
@Filter as varchar(8000)
)

select * from finhours
where (div_cde = @filter)
and date_from = @datefrom
and date_to = @dateto
and rank = @rank


GO

したがって、vb.netには、ストアドプロシージャを呼び出すサブルーチンがあります。これは、サブルーチンの正確なコードです。

Private Sub InsertPayRollRecords()
    Try
        'SQLConn.Open()

        sqlcomm.CommandText = "dbo.SP_INSERTVALUESINTOPR"

        sqlcomm.CommandType = CommandType.StoredProcedure

        sqlcomm.Parameters.Add("@DATEFROM", DateValue(dtpCFrom.Value))
        sqlcomm.Parameters.Add("@DATETO", DateValue(dtpCTo.Value))
        sqlcomm.Parameters.Add("@RANK", rank)
        sqlcomm.Parameters.Add("@FILTER", ReturnDivision())

        sqlcomm.Connection = SQLConn
        sqlcomm.CommandTimeout = 999999
        sqlcomm.ExecuteNonQuery()

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

@filterの値は次のようになります。

'AP0' OR div_cde = 'FO0'  OR div_cde = 'ME0'  OR div_cde = 'SO0'  OR div_cde = 'XO0'

問題は、これをVB.net 2000から起動したときに、エラーがまったく発生しないことです。

4

4 に答える 4

1

リストをストアドプロシージャに渡すことに気付いた場合は、代わりに「テーブル」を考えてください。手順は、テーブルまたはビューを参照できます。

select * from finhours
where 
and date_from = @datefrom
and date_to = @dateto
and rank = @rank
and div_cde in (select div_cde from interesting_division_codes)

通常、リストは任意ではありません。むしろ、彼らはいくつかのグループに属しています。その後、あなたは

select * from finhours
where 
and date_from = @datefrom
and date_to = @dateto
and rank = @rank
and div_cde in (select div_cde 
                from interesting_division_codes
                where div_category = @div_cat
                )

これは非常に好ましいです。処理がより効率的になり、より一貫した結果が得られます。言うまでもなく、それはグループの数とそのメンバーシップについてのいくつかのきらびやかな議論につながるでしょう。

div_cde値のリストをデータベース内で取得できず、プロセスごとである場合は、一時テーブルを使用します。それが本当に恣意的で、フィルター値が1回だけ使用される場合は、それらをテーブルパラメーターに挿入し、varcharの代わりにそれを渡して、クエリに結合します。

于 2013-01-09T07:57:02.213 に答える
0

あなたがSQLサーバーで動的なクエリ実行を必要とするよりもこのようなフィルターを持っているなら..あなたはsp_executesqlSQLサーバーの手順で行うことができます

DECLARE @SQLString nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);
DECLARE  datefrom1 smalldatetime;
DECLARE  @dateto1 smalldatetime;
DECLARE  @rank1 varchar(1);
DECLARE  @Filter1 varchar(8000);

/* Build the SQL string one time.*/
SET @SQLString =
     N'select * from finhours
       where (div_cde = @filter)
      and date_from = @datefrom
      and date_to = @dateto
      and rank = @rank';

SET @ParmDefinition = N'@datefrom1 as smalldatetime,
                         @dateto1 as smalldatetime,
                        @rank1 as varchar(1),
                        @Filter1 as varchar(8000)';


/* Execute the string with the first parameter value. */

EXECUTE sp_executesql @SQLString, @ParmDefinition,
                      @datefrom1 =@datefrom,
                      @dateto1 =@dateto,
                      @rank1 = @rank,
                      @Filter1 = @Filter;
于 2013-01-08T06:59:35.810 に答える
0

あなた@filterは書かれたように働くことができません。 where (div_cde = @filter)フィルタから単純な値を期待しています。

于 2013-01-08T07:00:14.553 に答える
0

あなたのアイデアのおかげで、私は私の問題に対する答えを見つけました。

動的SQLを使用する必要がありますが、SQL Server 2000ではnvarchar(4000)変数とvarchar(8000)変数のサイズが制限されているため、sp_executesqlを使用することはできないと思います。(ここで間違っている場合は訂正してください。)sp_executesqlは、4000サイズの制約であるnvarcharとして宣言する必要がある変数を使用しますが、実行する必要のあるクエリは16000+です。

(nvarchar(max)を使用せずにsp_executesqlでこれを起動するアイデアがある場合は、私に知らせてください。)

だから私はこの方法を使用しました

declare @QueryStart as string
declare @QueryBody as string
declare @Queryfrom as string
declare @querywhere as string

set @QueryStart  = <8000 character statement>
set @QueryBody = <8000 character statement>
set @Queryfrom = <8000 character statement>
set @querywhere = <8000 character statement>


exec (@QueryStart + @QueryBody + @Queryfrom + @querywhere)

SQLインジェクションの可能性があるため、この手順はお勧めしませんが、SQLServer2000で実行することを考えることができる唯一の方法です。

しかし、誰かがより効率的な答えを持っているなら、私に知らせてください:D

于 2013-01-21T03:10:49.803 に答える