Wednesday, March 7, 2012

Query of counts

I have a table with three fields: AcctNo INT, Code CHAR(1), Amount MONEY

The Code has three values: 'A', 'B', or 'C'.

Each AcctNo has 1, 2, or all 3 of the Codes assigned to it (ie. AcctNo is not unique)

I need to know how many AcctNos have one value assigned to the Code field, how many have two, and how many have three and I need to know the sum of the Amount for each group.

Can this be done in one statement or do I need three statements?

Fred

The query below returns the results as requested. Is this what you're looking for?

Chris

DECLARE @.Values TABLE (AcctNo INT, Code CHAR(1), Amount MONEY)

INSERT INTO @.Values(AcctNo, Code, Amount)

SELECT 1, 'A', 1.00 UNION

SELECT 1, 'B', 2.50 UNION

SELECT 2, 'C', 1.25 UNION

SELECT 3, 'C', 1.43 UNION

SELECT 3, 'A', 1.96 UNION

SELECT 3, 'B', 2.00 UNION

SELECT 4, 'C', 1.43 UNION

SELECT 4, 'A', 1.96 UNION

SELECT 4, 'B', 2.10 UNION

SELECT 5, 'B', 0.92 UNION

SELECT 5, 'A', 1.24 UNION

SELECT 6, 'C', 0.02 UNION

SELECT 7, 'B', 0.11

SELECT SUM([AccountNoCount]), SUM(TotalAmount), [CodeCount]

FROM (SELECT COUNT(DISTINCT AcctNo) AS [AccountNoCount], SUM(Amount) AS TotalAmount, COUNT(Code) AS [CodeCount]

FROM @.Values

GROUP BY AcctNo) t

GROUP BY [CodeCount]

|||

Yes, that is what I wanted first.

But I need to add another level of complexity. There are duplicates of the AccountNo and Code, only the Amount is different. I need to count duplicates as one. (or anything more than one; there were some with three times and four)

Thanks,

Fred

|||

All you should need is an extra DISTINCT, see below.

Chris

SELECT SUM([AccountNoCount]), SUM(TotalAmount), [CodeCount]

FROM (SELECT COUNT(DISTINCT AcctNo) AS [AccountNoCount], SUM(Amount) AS TotalAmount, COUNT(DISTINCT Code) AS [CodeCount]

FROM @.Values

GROUP BY AcctNo) t

GROUP BY [CodeCount]

Query ODBC timeout

The query builder in enterprise Manager(Database,Tables,Table,Open Table,
query) is giving me a timeout ODBC error on a long query.
Is there a way to configure the query builder? I can execute the query in
Query analyzer fine.I don't believe you can change Enterprise Managers query
timeout value. The workaround is to use Query Analyzer for
those types of queries. Enterprise Manager wasn't really
designed for executing long running queries.
-Sue
On Tue, 15 Aug 2006 10:27:02 -0700, MikeChicago
<MikeChicago@.discussions.microsoft.com> wrote:

>The query builder in enterprise Manager(Database,Tables,Table,Open Table,
>query) is giving me a timeout ODBC error on a long query.
>Is there a way to configure the query builder? I can execute the query in
>Query analyzer fine.|||MikeChicago wrote:
> The query builder in enterprise Manager(Database,Tables,Table,Open Table,
> query) is giving me a timeout ODBC error on a long query.
> Is there a way to configure the query builder? I can execute the query in
> Query analyzer fine.
Don't use Enterprise Manager for running queries or otherwise
manipulating data, it's not designed for that. Use Query Analyzer.
Tracy McKibben
MCDBA
http://www.realsqlguy.com

Query ODBC timeout

The query builder in enterprise Manager(Database,Tables,Table,Open Table,
query) is giving me a timeout ODBC error on a long query.
Is there a way to configure the query builder? I can execute the query in
Query analyzer fine.I don't believe you can change Enterprise Managers query
timeout value. The workaround is to use Query Analyzer for
those types of queries. Enterprise Manager wasn't really
designed for executing long running queries.
-Sue
On Tue, 15 Aug 2006 10:27:02 -0700, MikeChicago
<MikeChicago@.discussions.microsoft.com> wrote:
>The query builder in enterprise Manager(Database,Tables,Table,Open Table,
>query) is giving me a timeout ODBC error on a long query.
>Is there a way to configure the query builder? I can execute the query in
>Query analyzer fine.|||MikeChicago wrote:
> The query builder in enterprise Manager(Database,Tables,Table,Open Table,
> query) is giving me a timeout ODBC error on a long query.
> Is there a way to configure the query builder? I can execute the query in
> Query analyzer fine.
Don't use Enterprise Manager for running queries or otherwise
manipulating data, it's not designed for that. Use Query Analyzer.
Tracy McKibben
MCDBA
http://www.realsqlguy.com

Saturday, February 25, 2012

Query Notifications/ Service Broker problem

Hey , I encountered a problem using SqlDependency and notification services.

I’ve created a database with tools from c# Express 2005 and attached it to the sql server express 2005. And it turned out that ‘dependency_OnChange’ in my application is triggered each time I execute the command.ExecuteReader(); and it shouldn’t, because the command is just the select statement of columns and rows for which I wait to be modified.

SqlDependency dependency = new SqlDependency(command);

dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

command.ExecuteReader();//when the program gets here dependency_OnChange is called

So I Used the example from here :

http://msdn2.microsoft.com/en-us/library/a52dhwx7.aspx

and with AdventureWorks it behaves as it should , but when I change the connection string and select statement in the example to work with MyDatabase, the problem appears again.

So there is something wrong with MyDatabase ?

The select statement I used was “select Name, Pass from Users where Name like ‘L%’”;

So theoretically this should work but it does not and I end up in an infinite loop with

dependency_OnChange called cyclically …

I’d be grateful for any advice !

What are the dependency_OnChange paramater values passed in when the callback is notified?

I suspect the SqlNotificationEventArgs argument has a value of 'Subscribe' for the notification type, indicating an error in setting up the notification. If the statement you included is the exact statement you'd tried, then the problem is that your query is not respecting the Query Notifications restrictions. The query select Name, Pass from Users where Name like ‘L%’ is not properly schema bound, the Users table name should be bound with a schema name (e.g. dbo.Users).

HTH,
~ Remus

Query Notifications in SQL Express?

I am finding conflicting information about enabling query notifications for SQL Express. One book says it can be done and shows an example but most places on MSDN claim it requires the Service Broker. I am using Management Studio for SQL Express which does not show the Service Broker while an installation with SQL Server 2005 Dev Edition does show the Service Broker.

This is all very confusing. I want to be able to develop locally with SQL Express with Query Notifications and later deploy to a server which is more capable. Previously I have read that only real difference between SQL Server 2005 and SQL Express is a 2gb memory limit.

How would I go about setting up Query Notifications for SQL Express? Where would I find such documentation on MSDN?

I am partially past this problem. Upgrading SQL Express to SP1 has fixed this command from handing in Management Studio.

ALTER DATABASE AdventureWorks SET ENABLE_BROKER

Now I can see the Service Broker is enabled, but I guess I cannot really manage it, which is fine as long as I can still use the default queue for notifications. This query confirms it is on.

SELECT name,is_broker_enabled FROM sys.databases

By default the Service Broker is on for new databases but when I load the AdventureWorks database it is not enabled, so I had to get this working. Now I am stuck on these commands...

GRANT SUBSCRIBE QUERY NOTIFICATIONS TO brennan
GRANT SEND ON SERVICE::SqlQueryNotificationService TO brennan

The first one works but the second one fails. It says it does not recognize that service. I would like to know if there is a query I can run to see the available services.

Any help is appreciated.

Query Notifications filling up the transmission queue

I have a web application that sets up a query notification on a queue. Normal operation works fine, but for some reason the queue being monitored disables occasionally (even with the transaction, error message, and end dialog message) pattern set up as described in Remus' blog post. When the queue disables, everything goes insane and the transmission queue, left unchecked, fills up the transmission queue with hundreds of thousands of PostQueryNotification messages. Am I doing something wrong? What should I do to mitigate this because it IS possible that the queue might disable sometimes, and I don't want drive space eaten up on a low-end SQL Express machine, if it does. Also - second question - where is the transmission queue storing all these messages? TempDB?

I still haven't found a solution to this problem - even after applying normal poison message handling within the .NET code. Anyone? What to do about these query notifications filling up the xmit queue (and therefore the disk) when the queue disables?|||

One more question with regard to this behavior:

Why does service broker start a new conversation for each one of these notifications? This seems to compound the problem by not reusing a valid conversation_handle. I hope someone can provide an answer or solution to this soon because its close to holding up an intended launch at this point. Basically, I need to know what to do when a queue becomes disabled that is being monitored by a .NET application for query notifications. It seems like maybe I have to set up the architecture to receive the event notification in the .NET application and try to recover from code, rather than receiving it in SQL Server and recovering, which is what I would rather do.

|||

Even if it would reuse the conversations, the same number of notifications (messages) would be fired, so the transmission_queue would grow to the same size.

1) Why does the queue get disabled in the first place? In a development environment this occurs more often than normal because developers tend to debug applications and abruptly intrerupt execution, thus causing rollbacks that eventually disable the queue, but in a normal/test environment this should be a rare event. The fact that the queue gets disabled too often might indicate an application problem.

2) How many notifications are fired that the rate of growth for transmission queue is a issue of concern? Normally applications subscribe to a notification and then re-post the query when they are notified. So there should be a natural limit on the number of notifications fired and not delivered, since applications would not post new queries until the previous ones are notified. From your description it seems that new quesries are posted continuosly, which would indicate a problem in the application.

3) How did you set up and process the queue_diabled notification? Why did you had problems with this?

|||

Well, here is the setup of the notification, started on a separate thread from the main thread of the web application:

using (_command =

new SqlCommand("usp_ProcessMessage", _connection))

{

_command.CommandType = CommandType.StoredProcedure;

_command.CommandTimeout = 0;

string service = "service=myService" ;

_sqlNotificationRequest = new SqlNotificationRequest(new Guid().ToString(), service, 0);

_command.Notification = _sqlNotificationRequest;

while (true)

{

...

// BeginTransaction

// ExecuteReader

// Do Processing on Message

...

}

}

The stored procedure looks like this:

CREATE PROCEDURE [dbo].[usp_ProcessMessage]

AS

BEGIN

WAITFOR ( RECEIVE TOP ( 1 ) conversation_handle, message_type_name, message_body

FROM [tcp://MyQueue] ) ;

END

When [tcp://MyQueue] becomes disabled, the problems start. The question as to why the queue is becoming disabled is still under investigation and, I agree that this happens more in development. But, I am seeing it regularly, even with measures in place to dequeue the message and try to recover. In any case, even if I can isolate what is causing the queue to disable, I still need to have a recovery model in place - JUST IN CASE. So, is there something intrinsically wrong with the code above? Should I be doing something else? The number of PostQueryNotifications is definitely unmanageable when the queue disables....let me put it this way: they are filling up the sys.conversation_endpoints and sys.transmission_queue faster than I can end and delete them gracefully. A count yielded somewhere between 800,000 and 1M generated in the last 12 hours.

|||I don't really understand your code. The SqlNotificationRequest should be attached to a SqlCommand that retrieves the data to be notified from an user table (eg. a SELECT) and the RECEIVe statement should get the notifications when the content of the SELECT changes.
Your code attaches the SqlNotificationRequest to a SqlCommand that invokes the stored procedure containing the RECEIVE. I guess you get back immedeatly the notification that the subscription query is incorrect, not an actual notification.|||

Now I don't understand. I am trying to get an application notification whenever a message arrives in a queue. When I get the notification that something is there (in the queue), I want to RECEIVE and process the message(s). So can you help me understand how the commands are to be structured to achieve that?

Thanks again.

|||

Simply issue a SqlCommand.ExecuteReader() with the statement "WAITFOR (RECEIVE ...)" without setting up any SqlNotificationRequest. The RECEIVE statement will block until a message is available to be dequeued and processed by the application. Query Notifications is a generic mechanism for detecting changes on any data table, it does not work with message queues.

|||

OK, so can you explain what is happening in the code that I submitted? By attaching that notification to the command object that is calling the stored procedure with the WAITFOR(RECEIVE...), I am getting notifications for what? Or is it that I am simply getting a bunch of errors from the notification framework, as you mentioned?

If I understand you correctly, I don't need query notifications at all - just call that stored procedure normally; its on a different thread so it will block, but not the application, until a message arrives, at which time, the reader will RECEIVE and process the message? Is that correct?

|||

You should always check the XML payload of the received notifications and see wether is an actual notification or an error emssage. In your case you probably get similar to this: <qn:QueryNotification mlns:qn="http://schemas.microsoft.com/SQL/Notifications/QueryNotification" id="0" type="subscribe" source="statement" info="invalid" database_id="0" sid="..."><qn:Message>00000000-0000-0000-0000-000000000000</qn:Message>
</qn:QueryNotification>
The info="invalid" is the attribute that tells you that the submited query is not a valid one for notifications.

Query Notifications filling up the transmission queue

I have a web application that sets up a query notification on a queue. Normal operation works fine, but for some reason the queue being monitored disables occasionally (even with the transaction, error message, and end dialog message) pattern set up as described in Remus' blog post. When the queue disables, everything goes insane and the transmission queue, left unchecked, fills up the transmission queue with hundreds of thousands of PostQueryNotification messages. Am I doing something wrong? What should I do to mitigate this because it IS possible that the queue might disable sometimes, and I don't want drive space eaten up on a low-end SQL Express machine, if it does. Also - second question - where is the transmission queue storing all these messages? TempDB?

I still haven't found a solution to this problem - even after applying normal poison message handling within the .NET code. Anyone? What to do about these query notifications filling up the xmit queue (and therefore the disk) when the queue disables?|||

One more question with regard to this behavior:

Why does service broker start a new conversation for each one of these notifications? This seems to compound the problem by not reusing a valid conversation_handle. I hope someone can provide an answer or solution to this soon because its close to holding up an intended launch at this point. Basically, I need to know what to do when a queue becomes disabled that is being monitored by a .NET application for query notifications. It seems like maybe I have to set up the architecture to receive the event notification in the .NET application and try to recover from code, rather than receiving it in SQL Server and recovering, which is what I would rather do.

|||

Even if it would reuse the conversations, the same number of notifications (messages) would be fired, so the transmission_queue would grow to the same size.

1) Why does the queue get disabled in the first place? In a development environment this occurs more often than normal because developers tend to debug applications and abruptly intrerupt execution, thus causing rollbacks that eventually disable the queue, but in a normal/test environment this should be a rare event. The fact that the queue gets disabled too often might indicate an application problem.

2) How many notifications are fired that the rate of growth for transmission queue is a issue of concern? Normally applications subscribe to a notification and then re-post the query when they are notified. So there should be a natural limit on the number of notifications fired and not delivered, since applications would not post new queries until the previous ones are notified. From your description it seems that new quesries are posted continuosly, which would indicate a problem in the application.

3) How did you set up and process the queue_diabled notification? Why did you had problems with this?

|||

Well, here is the setup of the notification, started on a separate thread from the main thread of the web application:

using (_command =

new SqlCommand("usp_ProcessMessage", _connection))

{

_command.CommandType = CommandType.StoredProcedure;

_command.CommandTimeout = 0;

string service = "service=myService" ;

_sqlNotificationRequest = new SqlNotificationRequest(new Guid().ToString(), service, 0);

_command.Notification = _sqlNotificationRequest;

while (true)

{

...

// BeginTransaction

// ExecuteReader

// Do Processing on Message

...

}

}

The stored procedure looks like this:

CREATE PROCEDURE [dbo].[usp_ProcessMessage]

AS

BEGIN

WAITFOR ( RECEIVE TOP ( 1 ) conversation_handle, message_type_name, message_body

FROM [tcp://MyQueue] ) ;

END

When [tcp://MyQueue] becomes disabled, the problems start. The question as to why the queue is becoming disabled is still under investigation and, I agree that this happens more in development. But, I am seeing it regularly, even with measures in place to dequeue the message and try to recover. In any case, even if I can isolate what is causing the queue to disable, I still need to have a recovery model in place - JUST IN CASE. So, is there something intrinsically wrong with the code above? Should I be doing something else? The number of PostQueryNotifications is definitely unmanageable when the queue disables....let me put it this way: they are filling up the sys.conversation_endpoints and sys.transmission_queue faster than I can end and delete them gracefully. A count yielded somewhere between 800,000 and 1M generated in the last 12 hours.

|||I don't really understand your code. The SqlNotificationRequest should be attached to a SqlCommand that retrieves the data to be notified from an user table (eg. a SELECT) and the RECEIVe statement should get the notifications when the content of the SELECT changes.
Your code attaches the SqlNotificationRequest to a SqlCommand that invokes the stored procedure containing the RECEIVE. I guess you get back immedeatly the notification that the subscription query is incorrect, not an actual notification.|||

Now I don't understand. I am trying to get an application notification whenever a message arrives in a queue. When I get the notification that something is there (in the queue), I want to RECEIVE and process the message(s). So can you help me understand how the commands are to be structured to achieve that?

Thanks again.

|||

Simply issue a SqlCommand.ExecuteReader() with the statement "WAITFOR (RECEIVE ...)" without setting up any SqlNotificationRequest. The RECEIVE statement will block until a message is available to be dequeued and processed by the application. Query Notifications is a generic mechanism for detecting changes on any data table, it does not work with message queues.

|||

OK, so can you explain what is happening in the code that I submitted? By attaching that notification to the command object that is calling the stored procedure with the WAITFOR(RECEIVE...), I am getting notifications for what? Or is it that I am simply getting a bunch of errors from the notification framework, as you mentioned?

If I understand you correctly, I don't need query notifications at all - just call that stored procedure normally; its on a different thread so it will block, but not the application, until a message arrives, at which time, the reader will RECEIVE and process the message? Is that correct?

|||

You should always check the XML payload of the received notifications and see wether is an actual notification or an error emssage. In your case you probably get similar to this: <qn:QueryNotification mlns:qn="http://schemas.microsoft.com/SQL/Notifications/QueryNotification" id="0" type="subscribe" source="statement" info="invalid" database_id="0" sid="..."><qn:Message>00000000-0000-0000-0000-000000000000</qn:Message>
</qn:QueryNotification>
The info="invalid" is the attribute that tells you that the submited query is not a valid one for notifications.