Pulling data from a SQL table - sql

I have an Intranet, that is SQL based on the back end.
Users submit documents to the Intranet, but sometimes they set an expiry on the document.
There is a table "dbo.article" that lists all these documents, who submitted them and when (if ever) they expire. I get get this data by doing:
SELECT TOP 999 [NEWSID]
,[EXPIRES]
,[HEADLINE]
,[AUTHORID]
,[AUTHOR]
FROM [ARTICLE]
ORDER BY [EXPIRES] ASC
I would like this to run, say once a week, and then email me when an article is about to expire.
What would be the best way to achieve this?
Gavin.

a couple of ways to achieve this,
option 1 - write a stored procedure checking the expiry and sending notification emails if necessary, there are ways to send emails from sql server, for example, this link - How to send email from SQL Server?
option 2 - use some script (vbs or powershell, again, either use stored procedure or plain sql query) and when the condition is met, fire an email, and this is more flexible and could be installed at any client machine (not necessary on the SQL server). one sample on how to send email using vbs - http://social.technet.microsoft.com/Forums/en-US/7779b3bb-dfcc-4ab3-966d-9c71d5369ad7/send-email-using-vbscript
option 3 - implement a simple console app or even win form app to do stuff in option 2, instead of using script.
but all the options require you to add a scheduled task on the installed box to run it at your desired timeframe.

Related

EXASol set a custom session variable

In SQL Server (2016) we have the SESSION_CONTEXT() and sp_set_session_context to retrieve/store custom variables in a key-value store. These values are available only in the session and their lifetime ends when the session is terminated. (Or in earlier versions the good old CONTEXT_INFO to store some data in a varbinary).
I am looking for a similar solution in EXASol (6.0).
An obvious one would be to create a table and store this info there, however this requires scheduled cleanup script and more error prone than a built-in solution. This is the fallback plan, however I'd like to be sure that there is no other options.
Another option could be to create individual users in the database and configure them, but just because of the amount of users to be added, this was ruled out.
The use-case is the following: An application has several users, each user have some values to be used in each queries. The application have access only to some views.
This works wonderfully in SQL Server, but we want to test EXASol as an alternative with the same functionality.
I cannot find anything related in the EXASol Manual but it is possible, that I just missed something.
Here is a simplified sample code in SQL Server 2016
sp_set_session_context #key='filter', #value='asd', #read_only=1;
CREATE VIEW FilteredMyTable AS
SELECT Col1, Col2, Col3 FROM MyTable
WHERE MyFilterCol = CONVERT(VARCHAR(32), SESSION_CONTEXT('filter'))
I've tried an obviously no-go solution, just to test if it works (it does not).
ALTER SESSION SET X_MY_CUSTOM_FILTER = "asd"
You cannot really set a session parameter in EXASOL, the only way to achieve something similar is to store the values that you need in a table with a structure like:
SESSION_ID KEY VALUE READ_ONLY
8347387 filter asd 1
With LUA you could create a script that will make easier for you to manage these "session" variables.
I think you can achieve what you need by using the scripting capabilities within Exasol - see section 3.5 in the user manual..
You could also handle the parameterisation 'externally' via a shell script

how to execute stored procedure or query via batch file and send the results in email via batch file

I can execute the query via batch file and send it to the folder but I need to send the results to an email and I am not sure how to send the sql query/sp results in an email via batch file.
Any suggestions and help is appreciated.
Thanks
It sounds like you're executing your SQL query and I'm guess dumping it to a text file (let's say output.txt). I'm assuming Windows and I'm assuming SQL Server since you didn't specify. The answer is below, but I would like to offer two options instead:
OPTION 1: Setup SQL Server to send your email which would have several benefits including:
SQL Agency can control scheduling & logging
You get a SQL-Only solution
Email is centrally managed instead of being in a bunch of different batch files.
It's not hard to setup email in SQL and is clearly explained here:
How to send email from SQL Server?
OPTION 2: Use PowerShell to make your SQL call.
The answer to your question (below) uses PowerShell to send the email message. Since you'll use PS for that you might as well use PS to make your database call. You can find hundreds of examples of how to call SQL from PS.
Finally the answer you asked for...
If you want to continue to use a command line solution (maybe you have to kick off a bunch of non-SQL commands) you'll need to use PowerShell (assuming you don't want start making things complicated, like writing your own .exe).
STEP 1: Read the contents of the query (output.txt) by using:
$sqlOutput = Get-Content Output.txt -Raw
STEP 2: Use $sqlOutput as the body of the email. Here's a nice walkthrough:
http://www.howtogeek.com/120011/stupid-geek-tricks-how-to-send-email-from-the-command-line-in-windows-without-extra-software/
STEP 3: If you want to attach the file as an attachment, you can use the example here:
https://msdn.microsoft.com/en-us/library/system.net.mail.attachment(v=vs.110).aspx

Sync Framework between SQL Server 2008 and SQL Server CE

I'm working with a moderately sized database of about 60,000 records. I am working on building a mobile application which will be able to check out a single table into a compact .sdf on for viewing and altering on the device, then allow the user to sync their changes back up with the main server and receive any new information.
I have set it up with the Sync Framework using a WCF Service Library. When setting up the connection for some reason the database won't let me check "Use SQL Server Change Tracking" and throws up the error:
"'Unable to initialize the client database, because the schema for table 'Inventory' could >not be retrieved by the GetSchema() method of DbServerSyncProvider. Make sure that you can >establish a connection to the client database and that either the >SelectIncrementalInsertsCommand property or the SelectIncrementalUpdatesCommand property of >the SyncAdapter is specified correctly."
So I leave it unchecked and set it to use some already created columns "AddDateTime" and "LastEditTime" it seems to work okay, and after a massive amount of tweaking I have it partially working. The changes on the device sync up perfectly with the database, updates, deletes, all get applied. However, changes on the server side...never get updated. I've made sure everything is set up right with the bidirectional setup so that shouldn't be the problem. And, I let it sit overnight so the database received ~500 new records, this morning it actually synced the latest 24 entries to the database...out of 500 new. So that should be further proof that it's able to receive information from the server, but for all useful purposes, it's not.
I've tried pretty much everything and I'm honestly getting close to losing it. If anyone has any ideas they can throw out I can chase after I would be most grateful.
I'm not sure if I just need to go back and figure out why I can't do it with the "SQL Server Change Tracking". Or if there is a simple explanation for why it's not actually syncing 99% of the changes on the server back to the client.
Also, the server database table schema can't be altered as a lot of other services use it. But the compact database can be whatever the heck in needs to be to just store the table and sync properly in both directions.
Thank you!!
Quick Overview:
Using WCF and syncing without SQL Server Change Tracking (Fully enabled on server and database)
Syncing changes from client to server works perfectly
Syncing from server back to the client not so much: out of 500 new entries overnight, on a sync it downloaded 24.
EDIT: JuneT got me thinking about the time and their anchors. When I synced this morning it pulled 54 of about 300 new added records. I went in to the line (there are about 60 or so columns, so I removed them for readability, this is kind of a joke)
this.SelectIncrementalUpdatesCommand.CommandText = #"SELECT [Value], [Value], [Value] FROM >TABLE WHERE ([LastEditDate] > #sync_last_received_anchor AND [LastEditDate] <= >#sync_new_received_anchor AND [AddDateTime] <= #sync_last_received_anchor)";
And replaced #sync_last_received_anchor with two DIFFERENT times. Upon syncing it now returns the rows trapped between those two and took out the middle one giving me:
this.SelectIncrementalUpdatesCommand.CommandText = #"SELECT[Value], [Value], [Value] FROM >TABLE WHERE ([LastEditDate] > '2012-06-13 01:03:07.470' AND [AddDateTime] <= '2012-06-14 >08:54:27.727')"; (NOTE: The second date is just the current time now)
Though it returned a few hundred more rows than initially planned (set the date gap for 600, it returned just over 800). It does in fact sync the client up with the the new server changes.
Can anyone explain why I can't use #sync_last_received_anchor and what I should be looking for. I suppose I could always add box that allows the user to select the date to begin updating from? Or maybe add some sort of xml file to store the sync date that would be updated anytime a sync was -successfully- completed?
Thanks!
EDIT:
Ran the SQL profiler on it...the date (#sync_last_received_anchor) is getting set to 8 hours ahead of whatever time it really is. I have no idea how or why it's doing this, but that would definitely make sense.
Turns out the anchors are collected like this:
this.SelectNewAnchorCommand.CommandText = "Select #sync_new_received_anchor = GETUTCDATE()";
That UTC date is what was causing the 8 hours gap. To fix it either change it to GETDATE(), or convert your columns to UTC time in the WHERE clause of the commands.
After spending many hours with many cups of coffee, I've figured out how to solve this error of mine. While I was running the code on desktop testing area, everything seemed to be working perfectly; however the same code and webservice on target device gave this error repeatedly. Then, suddenly, the "dbo_" prefixes on compact database table names started looking interesting, like they were trying to tell me something really important. So, I've listened...
Configuration.SyncTables.Add("Products);
on ClientSyncAgent.cs should be changed to
Configuration.SyncTables.Add("dbo_Products");
[Exeunt]

Data Driven Subscriptions SSRS Standard Edition 2008

I'm fairly new to MSSQL and SSRS.
I'm trying to create a data driven subscription in MSSQL 2008 Standard SSRS that does the following.
Email the results of the report to a email address found within the report.
Run Daily
For Example:
Select full_name, email_address from users where (full_name = 'Mark Price')
This would use the email_address column to figure out who to email, This must also work for multiple results with multiple email address's.
The way I'm thinking of doing this is making a subscription to run the query, if no result is found then nothing happens.
But if a result is found then the report changes the row in Subscriptions table to run the report again in the next minute or so with the correct email information found in the results.
Is this a silly idea or not?
I've found a couple blog posts claiming this works but i couldn't understand their code enough to know what it does.
So, Any suggestions on how to go about this or if you can suggest something already out there on the internet with a brief description?
This takes me back to my old job where I wrote a solution to a problem using data-driven subscriptions on our SQL Server 2005 Enterprise development box and then discovered to my dismay that our customer only had Standard.
I bookmarked this post at the time and it looked very promising, but I ended up moving jobs before I had a chance to implement it.
Of course, it is targeted at 2005, but one of the comments seems to suggest it works in 2008 as well.
I've implemented something like this on SQL Server Standard to avoid having to pay for Enterprise. First, I built a report called “Schedule a DDR” (Data Driven Report). That report has these parameters:
Report to schedule: the name of the SSRS report (including folder) that you want to trigger if the data test is met. E.g. "/Accounting/Report1".
Parameter set: a string that will be used to look up the parameters to use in the report. E.g. "ABC".
Query to check if report should be run: a SQL query that will return a single value, either zero or non-zero. Zero will be interpreted as "do not run this report"
Email recipients: a list of semicolon-separated email recipients that will receive the report, if it is run.
Note that the “Schedule a DDR” report is the report we’re actually running here, and it will send its output to me; what it does is run another report – in this case it’s “/Accounting/Report1” and it’s that report that needs these email addresses. So “Schedule a DDR” isn’t really a report, although it’s scheduled and runs like one – it’s a gadget to build and run a report.
I also have a table in SQL defined as follows:
CREATE TABLE [dbo].[ParameterSet](
[ID] [varchar](50) NULL,
[ParameterName] [varchar](50) NULL,
[Value] [varchar](2000) NULL
) ON [PRIMARY]
Each parameter set – "ABC" in this case – has a set of records in the table. In this case the records might be ABC/placecode/AA and ABC/year/2013, meaning that there are two parameters in ABC: placecode and year, and they have values "AA" and "2013".
The dataset for the "Schedule a DDR" report in SSRS is
DDR.dbo.DDR3 #reportName, #parameterSet, #nonZeroQuery, #toEmail;
DDR3 is a stored procedure:
CREATE PROCEDURE [dbo].[DDR3]
#reportName nvarchar(200),
#parameterSet nvarchar(200),
#nonZeroQuery nvarchar(2000),
#toEmail nvarchar(2000)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
select ddr.dbo.RunADDR(#reportName,#parameterSet,#nonZeroQuery,#toEmail) as DDRresult;
END
RunADDR is a CLR. Here's an outline of how it works; I can post some code if anyone wants it.
Set up credentials
Select all the parameters in the ParameterSet table where the parameterSet field matches the parameter set name passed in from the Schedule A DDR report
For each of those parameters
Set up the parameters array to hold the parameters defined in the retrieved rows. (This is how you use the table to fill in parameters dynamically.)
End for
If there’s a “nonZeroQuery” value passed in from Schedule A DDR
Then run the nonZeroQuery and exit if you got zero rows back. (This is how you prevent query execution if some condition is not met; any query that returns something other zero will allow the report to run)
End if
Now ask SSRS to run the report, using the parameters we just extracted from the table, and the report name passed in from Schedule A DDR
Get the output and write it to a local file
Email the file to whatever email addresses were passed in from Schedule A DDR
Instead of creating a subscription to modify the subscriptions table, I would put that piece somewhere else, such as in a SQL agent. But the idea is the same. A regularly running piece of SQL can add or change lines in the subscription table.
A Google of "SSRS Subscription table" returned a few helpful results: Here's an article based on 2005, but the principles should be the same for 2008: This article is for 2008, and is really close to what you are describing as well.
I would just look at the fields one by one in the subscriptions table and determine what you need for each. Try creating a row by hand (a manual insert statement) to send yourself a subscription.
R-Tag supports SSRS data driven reports with SQL Server standard edition
You can use SQL-RD, a third-party solution, to create and run data-driven schedules without having to upgrade to SQL enterprise. It also comes with event-based scheduling (triggers the report on events including database changes, file changes, emails received and so on).

SQL Server Reporting Services 2005 - How to Handle Empty Reports

I was wondering if it is possible to not attach Excel sheet if it is empty, and maybe write a different comment in the email if empty.
When I go to report delivery options, there's no such configuration.
Edit: I'm running SQL Server Reporting Services 2005.
Some possible workarounds as mentioned below:
MSDN: Reporting Services Extensions
NoRows and NoRowsMessage properties
I should look into these things.
I believe the answer is no, at least not out of the box. It shouldn't be difficult to write your own delivery extension given the printing delivery extension sample included in RS.
Yeah, I don't think that is possible. You could use the "NoRows" property of your table to display a message when no data is returned, but that wouldn't prevent the report from being attached. But at least when they opened the excel file it could print out your custom message instead of an empty document.
Found this somewhere else...
I have a clean solution to this problem, the only down side is that a system administrator must create and maintain the schedule. Try these steps:
Create a subscription for the report with all the required recipients.
Set the subscription to run weekly on yesterday's day (ie if today is Tuesday, select Monday) with the schedule starting on today's date and stopping on today's date. Essentially, this schedule will never run.
Open the newly created job in SQL Management Studio, go to the steps and copy the line of SQL (it will look something like this: EXEC ReportServer.dbo.AddEvent #EventType='TimedSubscription', #EventData='1c2d9808-aa22-4597-6191-f152d7503fff')
Create your own job in SQL with the actual schedule and use something like:
IF EXISTS(SELECT your test criteria...)
BEGIN
EXEC ReportServer.dbo.AddEvent #EventType=... etc.
END
I have had success with using a Data-Driven Subscription and a table containing my subscribers, with the data-driven subscription query looking like this:
SELECT * FROM REPORT_SUBSCRIBERS WHERE EXISTS (SELECT QUERY_FROM_YOUR_REPORT)
In the delivery settings, the recipient is the data column containing my email addresses.
If the inner query returns no rows, then no emails will be sent.
For your purposes, you can take advantage of the "Include Report" and "Comment" delivery settings.
I imagine that a data-driven subscription query like this will work for you:
SELECT 'person1#domain.com; person2#domain.com' AS RECIPIENTS,
CASE WHEN EXISTS (REPORT_QUERY) THEN 'TRUE' ELSE 'FALSE' END AS INCLUDE_REPORT,
CASE WHEN EXISTS (REPORT_QUERY) THEN 'The report is attached' ELSE 'There was no data in this report' END AS COMMENT
Then use those columns in the appropriate fields when configuring the delivery settings for the subscription.