さまざまなデータを(テキストボックスとチェックボックスリストを介して)受け入れるフォームがあり、クリックイベントですべてのデータをテーブルに挿入し、scope_identityを選択して変数に格納し、チェックボックスリスト項目の挿入に使用します。別のテーブルへのループを使用する
多くの回答と例によると、これは完全に機能するはずです!..しかし、それは私にこのエラーを与えます:
Exception Details: System.InvalidCastException: Specified cast is not valid.
Line 66: int NewBrandId = (int)comm.ExecuteScalar();
これが私のリンクボタンメソッドコードです:
protected void lnkbtnUploadAndSubmit_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MOODbCenterConnection"].ConnectionString);
SqlCommand comm = new SqlCommand("INSERT INTO Brands (BrandName, BrandLogo, BrandWebsite, IsBrandVisible) VALUES (@Name, @Logo, @Website, @IsVisible); SELECT scope_identity();", conn);
comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 50);
comm.Parameters["@Name"].Value = txtbxBrandName.Text;
comm.Parameters.Add("@Logo", System.Data.SqlDbType.Text);
comm.Parameters["@Logo"].Value = fileuploadLogo.PostedFile.FileName;
comm.Parameters.Add("@Website", System.Data.SqlDbType.Text);
comm.Parameters["@Website"].Value = txtbxWebsite.Text;
comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit);
comm.Parameters["@IsVisible"].Value = chkbxIsPublished.Checked;
conn.Open();
int NewBrandId = (int)comm.ExecuteScalar();
conn.Close();
foreach (ListItem li in chkbxlstCuisines.Items)
{
if (li.Selected)
{
conn.Open();
SqlCommand comm2 = new SqlCommand("INSERT INTO BrandCuisines (CuisineId, BrandId) VALUES (@CuisineId, @NewBrandId)", conn);
comm2.Parameters.Add("@CuisineId", System.Data.SqlDbType.Int);
comm2.Parameters["@CuisineId"].Value = li.Value;
comm2.Parameters.Add("@NewBrandId", System.Data.SqlDbType.Int);
comm2.Parameters["@NewBrandId"].Value = NewBrandId;
comm2.ExecuteNonQuery();
conn.Close();
}
}
}
編集奇妙なことに、ビジュアルスタジオのSQL Server Expressで直接実行すると、クエリは正常に機能します。
この奇妙な問題の奇妙な説明
Alexbによる最初の解決策:
私はそれをしました:)私のSQLサーバー2008は「オブジェクト」にパックされたSystem.Decimalを返します。キャストの代わりにSystem.Convert.ToInt32を使用してみてください。
Example : int NewBrandId = System.Convert.ToInt32(comm.ExecuteScalar());
私による2番目の解決策:
「SELECTscope_identity();」を使用する代わりに「SELECTBrandIdFROM Brands WHERE BrandId = @@ Identity;」を使用しましたそれはあなたにさらに多くの制御を与えますが、私は個人的に最初の解決策を前払いします
N.B: "SELECT @@ Identity;"また、うまく機能します
みんなありがとう、そして私はそれが他の人を助けることを願っています!
正確にcomm.ExecuteScalar()
は何を返しますか?多分それはlong
またはdouble
に詰め込まれたobject
を返します。
正確には思い出せませんが、1〜2年前に何かに直面したようです。
SQLを変更できる場合、さらに簡単な方法は次のようになります。
SELECT CONVERT(int, SCOPE_IDENTITY())
Dimiが言ったように、IdentityはSQL数値(.NET Decimal)です。これは機能するはずです:
decimal decimalBrandId = (decimal)comm.ExecuteScalar();
int NewBrandId = (int)decimalBrandId;
SCOPE_IDENTITY()のドキュメントから
Return Types
numeric(38,0)
したがって、簡単な解決策は次のようになります
DECLARE @ReturnValue INT;
/*
Do your insert stuff here.
*/
SELECT @ReturnValue = SCOPE_IDENTITY();
SELECT @ReturnValue;