0

SQLDependencyを使用するアプリケーションがあります。新しい行が挿入されたときに、データベーステーブルに挿入された最新の行をユーザーに表示したいと思います。

これは、クエリが単純なselectステートメントの場合は期待どおりに機能しますが、最後に挿入された行を表示したいので、クエリをSELECT TOPステートメントとして記述しました。これにより、複数の例外が発生しました。この質問を確認TOPしたところ、SQLDependencyでは無効であることがわかったため、他の解決策を見つける必要があります。

これは私に2つのことを不思議に思いました:

A)SQLDependencyがTOP式をサポートしていない理由は何ですか?

B)私が思いついた解決策は、IDに基づいて結果を並べ替え、最後の結果を表示することです。これは正常に機能しますが、私のテーブルには現在非常に少ない行があります。データセットを使用しているので、行が追加されると速度が低下すると予想されます。そのため、クエリを最新の行のみに制限したかったのです。これを行うためのより良い方法はありますか?

4

2 に答える 2

5

この記事では、クエリ通知テクノロジがインデックス付きビューテクノロジをどのように活用するかについて説明します。したがって、同じ制限があります。効率的なインデックス付きビューを作成するには、テーブル内の他の行を参照せずに、現在の更新からのみインデックスを更新できる必要があります。TOPが許可される場合、百万ドルの質問は次のとおりです。TOPにあった行を削除した場合、どの行をその場所に配置する必要がありますか?これに答えるには、削除された行ではなく、TOPインデックス付きビューに含まれるはずの別の行をテーブルで検索する必要があります。したがって、TOP(または、まったく同じ問題に悩まされているMAXまたはMIN)を含むインデックス付きビューは、効率的に維持できず、許可されません。

クエリを実行すると、行が挿入されたことを検出できますCOUNT_BIG(*)。カウントが変更されたことが通知されたら、新しく挿入された行のクエリは簡単です。DELETES(つまり、誤検知)についても通知されます。

于 2012-09-12T19:54:03.887 に答える
0

@RemusRusanuはよく説明しました。SQLコマンドのキーワードは使用できませんTOPただし、一部のTOPデータを選択する場合は、以下の代替ソリューションを使用できます。

データベースからすべてのレコードを選択していますが、リストにレコードを10個だけ入れて、このリストをダッシュ​​ボードに戻しています。だから、最新の10枚のレコードを受け取るたびに。

TOPキーワードなしで現在のSQLコマンドを使用できます。私のは:

SQLコマンド:

Select [Id], [Name] FROM dbo.CUSTOMER where InsertDate = @InsertDate ORDER BY [ID] DESC;

次に、アプリケーションで、トップカウントに基づいてリストに入力できます。
以下のソースコードに関する私のコメントを確認してください。

public List<CustomerModel> GetAllCustomer()
        {
            List<CustomerModel> lstCustomerModel = new List<CustomerModel>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string InsertDate = string.Empty;
                InsertDate = DateTime.Now.ToString("yyyyMMdd");

                string query = "SELECT [Id] " +
                                    ",[Name] " +
                                "FROM [dbo].[Customer] where InsertDate = " + InsertDate + "   ORDER BY [Id] DESC;";
                SqlCommand cmd = new SqlCommand(query, conn);
                cmd.CommandType = CommandType.Text;
                cmd.Notification = null;
                SqlDependency.Stop(connectionString);
                SqlDependency.Start(connectionString);
                SqlDependency sqlDependency = new SqlDependency(cmd);
                sqlDependency.OnChange += OnDependencyChange;

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        int counter = 0;
                        while (reader.Read())
                        {
                            if (counter == 10) /* Here, I am reading just first ten record. After 10 records, I am not filling my List. So, It is kind of top 10 records.. Alternative solution.*/
                                break;
                            counter++;
                            
                            lstCustomerModel.Add(new CustomerModel
                            {
                               Id = Convert.ToInt32(reader.GetValue("Id")),
                               Name = WeightUnit = reader.GetValue("Name")
                            });

                            //break;
                        }
                    }
                }
            }

            return lstCustomerModel;
        }

        private void OnDependencyChange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                _context.Clients.All.SendAsync("refreshCustomers");
            }
        }
于 2020-08-04T22:32:47.210 に答える