SqlDependency simple select query always returns “Invalid”
-
01-06-2021 - |
Question
I'm trying to get the SqlDependency object to give me notifications, but so far I'm not able to get it working.
the sql query that I'm sending is this:
SELECT [SocialMedia].[dbo].[Items].[Id]
FROM [SocialMedia].[dbo].[Items]
I've tried it w/ and w/o the braces, having the fully qualified name, having only the variable name, and everything inbetween.
Id is of type Guid
which I didn't see any mention that they didn't work with SqlDependency objects in the Creating a Query for Notification article
I've also tried sending multiple columns over to see if that would work.
SELECT SocialMedia.dbo.Items.Id,
SocialMedia.dbo.Items.DateTimeCreated,
SocialMedia.dbo.Items.AuthorId
FROM SocialMedia.dbo.Items
And that also didn't work.
Here is my table SQL:
USE [SocialMedia]
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [dbo].[Items](
[Id] [uniqueidentifier] NOT NULL,
[DateTimeCreated] [datetimeoffset](7) NOT NULL,
[AuthorId] [uniqueidentifier] NOT NULL,
[Source] [varchar](max) NOT NULL,
[PlaceId] [uniqueidentifier] NULL,
[FullText] [varchar](max) NOT NULL,
[Geography] [geography] NULL,
[DateTimeAdded] [datetime] NULL,
CONSTRAINT [PK_Items] PRIMARY KEY CLUSTERED ( [Id] ASC )
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Items] WITH CHECK ADD CONSTRAINT [FK_Items_Places]
FOREIGN KEY([PlaceId]) REFERENCES [dbo].[Places] ([Id])
ALTER TABLE [dbo].[Items] CHECK CONSTRAINT [FK_Items_Places]
GO
ALTER TABLE [dbo].[Items] WITH CHECK ADD CONSTRAINT [FK_Items_Users]
FOREIGN KEY([AuthorId]) REFERENCES [dbo].[Users] ([Id])
ALTER TABLE [dbo].[Items] CHECK CONSTRAINT [FK_Items_Users]
And my DB:
USE [master]
GO
CREATE DATABASE [SocialMedia]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'SocialMedia',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.DENALI\MSSQL\DATA\SocialMedia.mdf' ,
SIZE = 1110016KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'SocialMedia_log',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.DENALI\MSSQL\DATA\SocialMedia_log.ldf' ,
SIZE = 123648KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [SocialMedia] SET COMPATIBILITY_LEVEL = 110
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) BEGIN
EXEC [SocialMedia].[dbo].[sp_fulltext_database] @action = 'enable'
END
GO
ALTER DATABASE [SocialMedia] SET ANSI_NULL_DEFAULT OFF
ALTER DATABASE [SocialMedia] SET ANSI_NULLS ON
ALTER DATABASE [SocialMedia] SET ANSI_PADDING ON
ALTER DATABASE [SocialMedia] SET ANSI_WARNINGS ON
ALTER DATABASE [SocialMedia] SET ARITHABORT ON
ALTER DATABASE [SocialMedia] SET AUTO_CLOSE OFF
ALTER DATABASE [SocialMedia] SET AUTO_CREATE_STATISTICS ON
ALTER DATABASE [SocialMedia] SET AUTO_SHRINK OFF
ALTER DATABASE [SocialMedia] SET AUTO_UPDATE_STATISTICS ON
ALTER DATABASE [SocialMedia] SET CURSOR_CLOSE_ON_COMMIT OFF
ALTER DATABASE [SocialMedia] SET CURSOR_DEFAULT GLOBAL
ALTER DATABASE [SocialMedia] SET CONCAT_NULL_YIELDS_NULL ON
ALTER DATABASE [SocialMedia] SET NUMERIC_ROUNDABORT OFF
ALTER DATABASE [SocialMedia] SET QUOTED_IDENTIFIER ON
ALTER DATABASE [SocialMedia] SET RECURSIVE_TRIGGERS OFF
ALTER DATABASE [SocialMedia] SET ENABLE_BROKER
ALTER DATABASE [SocialMedia] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
ALTER DATABASE [SocialMedia] SET DATE_CORRELATION_OPTIMIZATION OFF
ALTER DATABASE [SocialMedia] SET TRUSTWORTHY OFF
ALTER DATABASE [SocialMedia] SET ALLOW_SNAPSHOT_ISOLATION OFF
ALTER DATABASE [SocialMedia] SET PARAMETERIZATION SIMPLE
ALTER DATABASE [SocialMedia] SET READ_COMMITTED_SNAPSHOT OFF
ALTER DATABASE [SocialMedia] SET HONOR_BROKER_PRIORITY OFF
ALTER DATABASE [SocialMedia] SET RECOVERY FULL
ALTER DATABASE [SocialMedia] SET MULTI_USER
ALTER DATABASE [SocialMedia] SET PAGE_VERIFY CHECKSUM
ALTER DATABASE [SocialMedia] SET DB_CHAINING OFF
ALTER DATABASE [SocialMedia] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )
ALTER DATABASE [SocialMedia] SET TARGET_RECOVERY_TIME = 0 SECONDS
ALTER DATABASE [SocialMedia] SET READ_WRITE
And the code I'm using to run it:
string connString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
conn = new SqlConnection(connString);
conn.Open(); // open new connection and create command to notify about all new Chat-Messages in -ROOM_NUMBER- const
using (var sqlCommand = new SqlCommand(GetSearchQueryString(searchItems), conn))
{
var sqlDependency = new SqlDependency(sqlCommand
//handle onChange event - this will be fired whenever there is a change in database that affacts our query
sqlDependency.OnChange += (sender, e) =>
{
//change detected - get all messages...
try
{
var sql = GetSearchQueryString(searchItems);
int count = _entities.ExecuteStoreQuery<Guid>(sql).Count();
AsyncManager.Parameters["count"] = count;
}
finally
{
AsyncManager.OutstandingOperations.Decrement();
}
};
sqlCommand.ExecuteNonQuery();
}
I'm calling SqlDependency.Start(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString);
earlier in the program.
Am I missing something? I feel I'm missing something obvious...
Solution
We followed the steps described in http://dimarzionist.wordpress.com/2009/04/01/how-to-make-sql-server-notifications-work/
OTHER TIPS
I found SqlDependency to be very fragile. Sometimes, if you do something invalid, you always get a notification immediately. No error message.
Try to remove the database name qualification from the query. Reference the table like this: dbo.Items
It looks like you are using three part names, i.e.
[SocialMedia].[dbo].[Items].[Id]
The documentation clearly states you need to use two part names, so change to
[SocialMedia].[Items].[Id]
Michael's answer is an excellent source, but there's one thing that Microsoft omitted to mention:
The SQL Broker will reject SELECT statements on a table that has a computed column
If you try, you'll get an SqlNotificationEventArgs with info=Query, type=Subscribe, and like me you'll spend hours trying to figure out what's wrong with the statement, when it's the computed column that's the culprit.
Execute in your SQl Server
ALTER DATABASE YOURDBNAME SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE