Transmitting sessions id from SQL Server to web scripts - sql-server

I have a bunch of stored procs doing the business logic job in a SQL Server instance within a web application. When something goes wrong all of them queue a message in a specific table (let's say 'warnings') keeping track of the error severity and issue description. I want the web application using the stored procs to be able to query the message table at the end of the run but getting a list of the proper message only, i.e. the message created during the specific session or that specific connection: so I am in doubt if
have the web application send to the db a guid to INSERT as column value in the message records (but somehow I have to keep track of it in several stored procs running at the page level, so I need something "global")
OR
if I can use some id related to the connection opened by the application - and this would be definitely more sane. Something like (this is pseudo code):
SELECT #sessionid = sessionid FROM sys.something where this = that
Have some hints?
Thanks a lot for your ideas

To retrieve your current SessionId in SQL Server you can simply execute the following:
select ##SPID
See:
http://msdn.microsoft.com/en-us/library/ms189535.aspx

Related

Crystal Reports creating temporary table with SQL Server

I'm using Crystal Reports 2008 with SQL Server 2014.
I read on the internet that it was possible to create a temporary table with Crystal Reports. This link says that, one of many examples -> Click here
Yet when I go to the database expert, create a new command and enter the following DDL
CREATE TABLE #temp_test (col1 VARCHAR(5))
I get this error
Translation:
database connector error : 'No error message from server'
Yet, when I'm doing that with SQL Server on my database, everything is fine.
Have you managed to do it? If yes, how?
It sounds like an urban legend to me but I might be wrong...
Cheers
When you create a "Command" table in Crystal, you're giving Crystal a set of text to send to the SQL server, and Crystal expects a data set in return. Everything in between is done on the SQL server. Crystal checks the command by sending it to the SQL server when you enter it to see if it works.
Given that, your temp table is actually created on the SQL server. Also, when you create a temp table, it is deleted after the command is finished running.
As a result, if you use only this code, the SQL server will create the table, but there is no data set to return. It succeeds, so doesn't return an error, but also doesn't return data, hence the message: "No error message from server".
For your next step, I would suggest using code like this:
CREATE TABLE #temp_test (col1 VARCHAR(5))
SELECT * FROM #temp_test
This will create an empty data set to return to Crystal, so that it's getting the response it needs. I say this so that you don't think anything is wrong when you don't see anything. You'll need to insert data into the temp table in order to get it from the select statement for visual confirmation.
I would also suggest that you don't use a temp table unless you determine that you do or will actually need one within the scope of the command. For example, you may need one to increase performance on a particularly complex query or CTE, so it might increase performance to use a temp table. But I would create that query first and worry about optimization after I have at least some of it developed.

How to push the data from database to application?

I want to push the data from database to application instead of application pull the data. I have installed ms sql server and apache tomcat server. I have my application in apache tomcat, here I made connection to database. Now I want database send the data whenever there is update in data. But all I know is fetch the data from database is not good idea, because application needs to monitor the database for updated data will lead to fire the query for every 5 sec, this is not efficient as well.
I google it I got some answers they are Query Notification here, Sql server Agent Job to schedule the task automatically. If you have any other suggestion please post it.
There surely are several possibilities to do that:
Implement unsafe CLR trigger
Implement unsafe CLR procedure
Use xp_cmdshell
Call web service
Use Query Notification
You can read a little about them in this discussion:
Serial numbers, created and modified in SQL Server.
Personally I would prefer Query Notification over other methods, because it already has support fopr various cases (e.g. sync/async communication) and you don't have to reinvent the wheel. And is in your case recommended by Microsoft.
Polling is another method you've mentioned. It's is a more like traditional method and there can be some performance penalties related, but you shouldn't worry about them if you are careful enough. For example, if you already have an authentication built in your application, you can create another column in your Users table that is set if there are any changes related to that user. And then, there can be just a thread in your app that will perform a query every second against this table (even dirty reads with NOLOCK shouldn't be a problem here) and maintain some in-memory structure (e.g. thread-safe dictionary) that says which client should get pushed. Another thread polls your dictionary and when it finds there something for the client, performs a db query that extracts data and sends it to the client. This looks like a lot of unnccessary work, but at the end you get two independent workers which somewhat helps to separate concerns; first one is just an informer which performs 'lightweight' database polling; second one extract real data and performs server push. You can even optimize the push-worker in the way that when it runs, it checks if multiple clients need some data and then executes the select for all of those who need it. You would probably want the second worker to run less frequently than first one.
EDIT
If you wish to use non-.NET technology to achieve the same functionality, you will have to get more into SQL Server Service Broker. Query Notification is a simplified layer built in .NET on top of SQL Server Service Broker, and you would have to build at least part of that layer by yourself. This includes creating queue, message type, service and stored procedures with SEND and RECEIVE on the other side. You will have to take care of the conversation/dialog by yourself. SB is actually a async-messaging world adjusted to work in RDBMS environment, so you will see some new TSQL expressions. However, MSDN is here to help:
http://msdn.microsoft.com/en-us/library/ms166061(v=sql.105).aspx
http://msdn.microsoft.com/en-us/library/bb522893.aspx
This could help as well: Externally activate non-.NET application from Service Broker
Example on how to code the stuff:
-- First you have to enable SB for your database
USE master
ALTER DATABASE Playground
SET ENABLE_BROKER
GO
USE Playground
GO
-- Then create a message type; usually it will be XML
-- because it's very easy to serialize/deserialize it
CREATE MESSAGE TYPE [//Playground/YourMessageType]
VALIDATION = WELL_FORMED_XML
GO
-- Then create a contract to have a rule for communication
-- Specifies who sends which message type
CREATE CONTRACT [//Playground/YourContract] (
[//Playground/YourMessageType] SENT BY ANY)
GO
--Creates queues, one for initiator (1) and one for target (2)
CREATE QUEUE MyQueue1
GO
CREATE QUEUE MyQueue2
GO
-- Finally, configure services that 'consume' queues
CREATE SERVICE [//Playground/YourService1]
ON QUEUE MyQueue1 ([//Playground/YourContract])
GO
CREATE SERVICE [//Playground/YourService2]
ON QUEUE MyQueue2 ([//Playground/YourContract])
GO
-- Now you can send a message from service to service using contract
DECLARE
#dHandle uniqueidentifier,
#Msg nvarchar(max)
BEGIN DIALOG #dHandle
FROM SERVICE [//Playground/YourService1]
TO SERVICE '//Playground/YourService2'
ON CONTRACT [//Playground/YourContract]
WITH ENCRYPTION = OFF
SELECT #Msg = (
SELECT TOP 3 *
FROM Table1
FOR XML PATH('row'), ROOT('Table1'))
;SEND ON CONVERSATION #dHandle
MESSAGE TYPE [//Playground/YourMessageType] (#Msg)
PRINT #Msg
GO
-- To get the message on the other end, use RECEIVE
-- Execute this in another query window
DECLARE #dHandle uniqueidentifier
DECLARE #MsgType nvarchar(128)
DECLARE #Msg nvarchar(max)
;RECEIVE TOP(1)
#dHandle = conversation_handle,
#Msg = message_body,
#MsgType = message_type_name
FROM MyQueue2
SELECT #MsgType
SELECT #Msg
END CONVERSATION #dHandle
GO

Data sync check among two SQL Server database

We've two SQL server database. The source server has data populated from an external system and a destination database on a remote server (used by a web app). There's an SSIS package which maps column from source tables to destination (column names differ) and populates data to maintain the sync.
Now, to ensure that both the database are in sync for which we've an SP which shows record count and for some parent-child relationships it shows child count for each parent record (i.e. Brandwise Item count). Someone has to logon to both the servers, execute the SP and get the data manually. Then compare the results to ensure that both the db are in sync.
Now, to automate this process, we've done the following-
Add the destination server as a "Linked Server"
Use "EXEC msdb.dbo.sp_send_dbmail" along with "#attach_query_result_as_file =1"
Create an SSIS job which will execute the email SP for both the servers
So, this is how we get two emails which has query results attached to
it. And then comparing the text files completes the db sync check.
I believe this can be made better - now that we're able to access the destination server as a linked server. Its my first time so I'd request some experienced guys to share their approach, probably something beyond a join query with the linked server.
Since you have access to server as Linked server you can directly run query and compare data.
Please check this
You can modify SSIS jobs to send mails based on this query result.
I'm using the following query which is a simple version and gives me differences of both the sides -
(Select s.Title, s.Description from ERPMasterBrand as s EXCEPT
Select d.Title, d.Description from MasterBrand as d)
UNION
(Select s.Title, s.Description from MasterBrand as s EXCEPT
Select d.Title, d.Description from ERPMasterBrand as d)
Any better suggestions? I've tested and it gives desired results - hope I'm not being misguided :-) by my own solution.

how to push data or message from sql server to web application

I'm developing a asp.net MVC 3 web application project. The project is simple, it provides a web page listing stored procedures in SQL Server. when user selects a stored procedure and hit "run" button, it is invoked to execute in SQL Server and return some execution result.
My stored procedure is logically divided into several steps, say 10 steps, each step prints a message like step 1: doing A..., step2: dong B..., until step 10: done or step 10: fail. (with error message).
I don't want the user just hang on to wait until stored procedure finishes and just see the final result message. I want them to see some kind of live execution of stored procedure, so that user is well updated of where the stored procedure is.Some stored procedures are quick and take few seconds to finish, some are very slow and take even 1 hour to finish.
Now the question is: how could I push theses step messages from SQL Server to web application, so that in web browser, user can see each step message get printed in real-time fashion?
I search lots of info, the best i can see is model controller notifies view once there's change in model, but still need model controller to pull from SQL Server, I don't see any real push from SQL Server to web application. Your advice is highly appreciated.
One approach would be to create a log table at the start of the procedure, with a unique name. The MVC code would display a grid or other element showing this log table, the stored procedure would simply add rows to the table after each step is complete...
Grab the session ID of the connection
The procedure creates a file called LOG_SessID
The MVC opens the table and uses the Meta Refresh or a Timer to redisplay the page
Each redisplay checks to see if the table still exists, if not, it
assumes the procedure is done and prints the appropriate message
One possible solution can be that you break your SP into steps and call each Step's SP and update the User screen (even have separate MVC VIEWS/PARTIAL VIEWS for each step's success and failure) based on the result!

How to check if an JPA/hibernate database is up with second-level caching

I have a JSP/Spring application using Hibernate/JPA connected to a database. I have an external program that check if the web server is up every 5 minutes.
The program call a specific URL to check if the web server is still running. The server returns "SUCCESS". Obviously if the server is now, nothing is returned. The request timesout and an alert is raised to inform the sysadmin that something is wrong...
I would like to add another layer to this process: I would like the server to return "ERROR" if the database server is down. Is there a way using Hibernate to check if the database server is alive and well?
What I tought to do was to take an object and try to save it. This would work, but I think it's probably too much for what I want. I could also read(load) an object from the database. But since we use second-level caching for all our objects, the object will be loaded from the cache, and not the database.
What I'm looking for is something like:
HibernateUtils.checkDatabase()
Does such a function exist in Hibernate?
You could use a native query, e.g.
Query query = sess.createNativeQuery("select count(*) from mytable").setCacheable(false);
BigDecimal val = (BigDecimal) query.getSingleResult();
That should force hibernate to use a connection from the pool. If the db is down, I don't know exactly what will be the error returned by hibernate given that it can't get the connection from the pool. If the db is up, you get the result of your query.

Resources