私はこのタイプの質問がSOで少なくとも十数回尋ねられたことを知っていますが、私はここで見つけることができた以前のすべての質問と回答を調べましたが、私が見つけたものは当てはまりません。ページで複数のFormViewオブジェクトを使用していますが、そのうちの1つを編集するオプションを追加したいと思います。FormViewは、ストアドプロシージャにリンクされたSqlDataSourceによって入力されるため、レコードを更新するストアドプロシージャを作成し、それをSqlDataSourceに追加しました。これは次のようになります。
<asp:SqlDataSource ID="TestSqlDataSource" runat="server"
SelectCommandType="StoredProcedure"
ConnectionString="<%$ ConnectionStrings:development %>"
SelectCommand="usp_GetNewTestDetails"
UpdateCommand="usp_UpdateTest"
UpdateCommandType="StoredProcedure"
onupdating="TestSqlDataSource_Updating">
<SelectParameters>
<asp:SessionParameter SessionField="TestID" Name="TestID"/>
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="testId" Type="Int32"/>
<asp:Parameter Name="testerLicense" Type="Int32" />
<asp:Parameter Name="premiseOwner" Type="String" />
<asp:Parameter Name="premiseAddress" Type="String" />
<asp:Parameter Name="premiseCity" Type="String" />
<asp:Parameter Name="premiseState" Type="String" />
<asp:Parameter Name="premiseZip" Type="String" />
<asp:Parameter Name="protectionType" Type="String" />
<asp:Parameter Name="testType" Type="String" />
<asp:Parameter Name="repairs" Type="String" />
<asp:Parameter Name="notes" Type="String" />
<asp:Parameter Name="testDate" Type="DateTime" />
<asp:Parameter Name="employerName" Type="String" />
<asp:Parameter Name="employerAddress" Type="String" />
<asp:Parameter Name="phoneNumber" Type="String" />
<asp:Parameter Name="emailAddress" Type="String" />
<asp:Parameter Name="dataEntryName" Type="String" />
<asp:Parameter Name="dataEntryPhone" Type="String" />
<asp:Parameter Name="signature" Type="String" />
<asp:Parameter Name="entryDate" Type="DateTime" />
</UpdateParameters>
</asp:SqlDataSource>
レコードを更新しようとすると、クエリにパラメータが多すぎるというエラーが表示されます。コード内のパラメーター(名前、番号、さらには順序)がストアドプロシージャ内のパラメーターと正確に一致することをトリプルチェックしました。
答えを見つけようとして、私はこのサイトを参照しているこの投稿に出くわしました(元のサイトがダウンしているように見えるため、archive.orgにアクセスする必要がありました)。関数にパラメーターを追加するために彼らが提案したものを適用しました。私が見つけたのは、ストアドプロシージャに、更新プロシージャに含まれていないselectプロシージャからの「ルックアップ」値がいくつかあることです。更新しようとしているテーブルにはテスターのIDしかありませんが、ユーザーは自分の名前も表示したいので、そのテーブルを参照しますが、FormViewでは、これらのフィールドは編集モード中は読み取り専用であるため、それを変更しようとしないでください。他のすべてのパラメータが並んでいます...それらのルックアップ値のみがオフになっています。trace
渡すパラメータの特定のリストを含めることで、それらのパラメータのみを使用すると思いましたが、それは正しくないようです。すでにパラメータを指定しているので困惑していますが、selectストアドプロシージャのパラメータで上書きされていることはどこにもわかりません。これらの読み取り専用の値を使用しないようにするには、どこに指示すればよいですか?
これらはユーザーが必要とするため、元のストアドプロシージャから削除したくありません。私がこれまでに思いついた回避策の1つは、それらをストアドプロシージャに追加してから、決して使用しないことです。私はこれがうまくいくとかなり確信していますが、それは問題を修正するのではなく、問題を隠蔽するだけです。
編集:リクエストごとに追加のコード
これは、パラメータをtrace
関数に出力するメソッドです。
protected void TestSqlDataSource_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
for (int i = 0; i < e.Command.Parameters.Count; i++)
{
Trace.Write(e.Command.Parameters[i].ParameterName);
if (e.Command.Parameters[i].Value != null)
{
Trace.Write(e.Command.Parameters[i].Value.ToString());
}
}
}
これは、更新に使用されるストアドプロシージャです。
ALTER PROCEDURE [dbo].[usp_UpdateTest]
@testId INT ,
@testerLicense INT ,
@premiseOwner VARCHAR(50) ,
@premiseAddress VARCHAR(150) ,
@premiseCity VARCHAR(50) ,
@premiseState VARCHAR(2) ,
@premiseZip VARCHAR(10) ,
@protectionType VARCHAR(11) ,
@testType VARCHAR(2) ,
@repairs VARCHAR(200) ,
@notes VARCHAR(300) ,
@testDate DATETIME ,
@employerName VARCHAR(50) ,
@employerAddress VARCHAR(150) ,
@phoneNumber VARCHAR(25) ,
@emailAddress VARCHAR(60) ,
@dataEntryName VARCHAR(50) ,
@dataEntryPhone VARCHAR(25) ,
@signature VARCHAR(50) ,
@entryDate DATETIME
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.Tests
SET TesterLicense = @testerLicense ,
PremiseOwner = @premiseOwner ,
PremiseAddress = @premiseAddress ,
PremiseCity = @premiseCity ,
PremiseState = @premiseState ,
PremiseZip = @premiseZip ,
ProtectionType = @protectionType ,
TestType = @testType ,
Repairs = @repairs ,
Notes = @notes ,
TestDate = @testDate ,
EmployerName = @employerName ,
EmployerAddress = @employerAddress ,
PhoneNumber = @phoneNumber ,
EmailAddress = @emailAddress ,
DataEntryName = @dataEntryName ,
DataEntryPhone = @dataEntryPhone ,
Signature = @signature ,
EntryDate = @entryDate
WHERE TestID = @testId
END