私のアプリケーションでは、複数のデータベーステーブル(外部キーで参照)からのデータを含むDataTableにGridControlをバインドします。SqlDataAdapterを使用したデータベースビューの更新
複数のデータベーステーブルを参照するコマンドでSqlDataAdapterを使用していたため、データの更新に問題がありました。私はエラーを取得した
Dynamic sql generation is not supported against multiple base tables
私はその後、私のGRIDCONTROLに特異的に結合することができることを一つの「表」の中に複数のテーブルを結合したビューを作成することによって、それを周りに動作するようにしようとしました。
適切なデータを適切なテーブルに追加していたビューで、「代わりに」トリガを使用してデータを挿入しました。プレーンなt-SQLでは、インサートは完全に機能します。私は自分のビューにデータを挿入することができ、それは適切なテーブルに挿入されています。私のSqlDataAdapterは1つの "テーブル"を更新し、残りの更新はトリガーによって行われているため、更新に問題はありません。
残念ながら、私はまだエラー
Dynamic sql generation is not supported against multiple base tables
を取得していますが、SqlDataAdapterオブジェクトは、まだ私が更新させていない理由を任意のアイデアを持っていても、それは今だけ1「テーブル」を更新しています思いました - か?
マイコード:
ビュー:
CREATE view [dbo].[v_TestTypeParameter_grid]
as
(
select t1.Id, t3.Name, t3.Description, t2.MinValue, t2.MaxValue, t4.Symbol
from TestTypes as t1 join
TestTypeParameters as t2 on t1.Id = t2.TestType join
Parameters as t3 on t2.Parameter = t3.Id left join
Units as t4 on t2.Unit = t4.Id
)
代わりのビューにトリガー:
CREATE TRIGGER [dbo].[tr_TestTypeParameterAdded] ON [dbo] [v_TestTypeParameter_grid]
INSTEAD OF INSERT
AS
BEGIN
DECLARE
@TestTypeId int,
@ParameterId int,
@UnitId int,
@ParameterName varchar(100),
@MinValue decimal(18,2),
@MaxValue decimal(18,2),
@UnitSymbol varchar(100)
SELECT @TestTypeId = Id, @ParameterName = Name, @MinValue = MinValue, @MaxValue = MaxValue, @UnitSymbol = Symbol FROM Inserted;
SELECT @ParameterId = Id FROM Parameters WHERE Name = @ParameterName;
SELECT @UnitId = Id from Units WHERESymbol = @UnitSymbol;
INSERT INTO TestTypeParameters(TestType, Parameter, MinValue, MaxValue, Unit) VALUES(@TestTypeId, @ParameterId, @MinValue, @MaxValue, @UnitId);
END
マイ結合コード:
mvarParameterListAdapter = DBService.GetDataAdapter("select * from v_TestTypeParameter_grid where Id = " + mvarTestTypeId);
mvarParameterTable = new DataTable();
mvarParameterListAdapter.Fill(mvarParameterTable);
gcParameters.DataSource = mvarParameterTable;
gcParameters.RefreshDataSource();
DBService.GetDataAdapter方法。
public static SqlDataAdapter GetDataAdapter(String command, DataTable parameters = null)
{
SqlConnection lvarConnection = GetConnection();
SqlCommand lvarCommand = new SqlCommand(command, lvarConnection);
if (parameters != null && parameters.Rows.Count > 0)
{
foreach (DataRow lvarRow in parameters.Rows)
{
lvarCommand.Parameters.AddWithValue("@" + lvarRow[0], lvarRow[1]);
}
}
SqlDataAdapter lvarAdapter = new SqlDataAdapter(lvarCommand);
SqlCommandBuilder lvarCommandBuilder = new SqlCommandBuilder(lvarAdapter);
return lvarAdapter;
}
アップデートコード:T-SQLで動作
try
{
mvarParameterListAdapter.Update(mvarParameterTable);
}
catch (Exception ex)
{
// Here, I'm getting the error
}
の挿入:
INSERT INTO v_TestTypeParameter_grid VALUES (2, 'Fe', 'Iron', 5.2, 7.9, '%')
私は(別のデータで)このように動作し、いくつかのGridControlsを持っているので、私がしようとしていますSqlDataAdapterの代わりにselect、insert、update、deleteのコマンドを生成するのではなく、SqlCommandBuilderを使用してよりシンプルにしています。
ありがとうございます!
EDIT:
に(たぶん)、物事を明確にする:
これは私が働いているGRIDCONTROLです。列名を私に許してください、彼らはポーランド語です。 Identyfikator =同上、 Nazwa =名前、 OPIS =説明、 最小= MinValueプロパティ、 Maksimum = MaxValueを、 Jednostka =単位
今のところ、私は唯一の「Nazwaを(含まれていることをGRIDCONTROLに別の行を追加してい名前)」および「Opis(Description)」フィールドがあります。
"Identyfikator(Id)"フィールドに、パラメータを追加するTestTypeのIDと他のフィールドのデフォルト値を入力します。新しい行は、GridControlにバインドされているDataTableに自動的に追加され、ユーザーが[保存]をクリックすると、SqlDataAdapter.Update()メソッドを使用してその変更をデータベースにプッシュします。ここでエラーが発生しています:
私が達成したいことと、それをどうしようとしているのかを明確にしたいと思っています。
編集:
この問題の解決策を見つけることができました。あなたは私の答えでそれをチェックすることができます。
あなたには大きな欠陥があります。挿入された行は1つしかないと仮定します。これは、SQL Serverのトリガーの仕組みではありません。 1回の操作で1回発射されます。これを単一のセットベースの挿入として記述し、それらのスカラー変数を取り除く必要があります。挿入されてからパラメータとユニットへの単純な結合のように見えるトリガーの問題を修正します。また、パラメータ化されたクエリについても読んでおく必要があります。あなたが投稿したものは、SQLインジェクションに脆弱です。 –
@SeanLange SQLトリガーは操作ごとに1回起動することを知っています。できるだけクリーンで更新を行う方法を見つけようと数時間を費やしていたので、更新が正常に機能しているかどうかを確認したいテストバージョンです。私はまた、どのようなパラメータ化されたクエリがあるか知っていますし、GetDataAdapterメソッドで見ることができるように、パラメータを使用する可能性がありますが、やはりテスト版です。 –
あなたの記事では更新について話していますが、このコードのどこにでも単一の更新ステートメントは表示されません。また、更新を行っている他のトリガーについても触れています。私たちがすべての情報を持っていないと、本当に助けが難しいです。問題がどこにあるかわかるように詳細を投稿できますか? –