Execute query once in SQL Server despite being called mutiple times - sql-server

I have a situation where a query might be called multiple times from multiple users, but I only want it to run once (per week) against the database. The environment is SQL Server Express so scheduling via SQL Server Agent is not an option. It needs to be 2005 compatible. I'd like to make it as lightweight as possible too, so I'm asking for suggestions. Ideally a database wide declared variable - but I don't think that SQL Server supports such a beast? Thanks

Try something like this:
IF NOT EXISTS ( -- Check if you have the current week content
SELECT *
FROM WeeklyTable
WHERE
DATEPART(YEAR, DateCr) = DATEPART(YEAR, GETDATE())
AND
DATEPART(WEEK, DateCr) = DATEPART(WEEK, GETDATE())
)
BEGIN
-- delete old content
DELETE WeeklyTable
-- insert new content
INSERT INTO WeeklyTable (MyID, MyField1, ... , MyFieldN, DateCr)
SELECT
MyID, MyField1, MyField2, GETDATE()
FROM MainTable
END
You can create indexes you need for the WeeklyTable.

One option would be SQL Scheduler as a add-on to SQL Server Express.
The other option would be to create a small command-line utility that does the querying and schedule that using the Windows Scheduler on the machine where SQL Server Express is installed.
With either of the two setups, you could select the values / numbers you need into a result table once a week, and any requests during the week would be satisfied from that one result table. SQL Server doesn't have "server-wide" variables - but you can always define a table for that purpose...

Related

SSRS rdl preview shows date with bad value shows up despite SQL query that should exclude it

SSRS rdl preview shows date with bad value shows up despite SQL query that should exclude it.
The xml for the query in the rdl-file is:
<Query>
<DataSourceName>ourDataSource</DataSourceName>
<CommandText>
use ourDataBase
----------------------------------------
select convert(date, Date1) as ourDate1, count(*) as ourCountForDate
from ourDataBase.dbo.ourTable
where
(
(Date1 between (getDate()-365) and (getDate()+1) )
)
group by convert(date, Date1)
order by convert(date, Date1)
</CommandText>
<rd:UseGenericDesigner>true</rd:UseGenericDesigner>
</Query>
This query works just fine in the SQL database when using TSQL directly in SSMS.
However, there is a stray value with a strange year in the database (such as 7654), and it shows up in the results for the rdl file in 'preview' but NOT in the SQL-query results in SSMS.
I have tried lots of variants, with greater than or equal to, and so forth, but this stray value always shows up.
I am using SSRS, Visual Studio 2015, with underlying TSQL. The SSRS uses 2016/01/reportdefinition. The SQL server for the project is SQL Server 2008 R2, 2012 or 2014.
Any ideas?
It's better to create a stored procedure in SQL Server and then have the SSRS call that. Can perform better too. This keeps the data control entirely in the SQL Server.
For those not wanting to use stored-procedures (e.g. due to having to migrate them from various database regions), this worked for me:
Deleting the associated ".data" file helped, also, 'clean' and 'rebuild' the project.
One can also try things like make sure the year starts with 2 (or for some is less than 3).
Here is how one checks for starting with 2:
( left(Datepart(yyyy, Date1),1) = '2' )

How to delete a table after a period of inactivity?

For the purpose of my project I cannot use session based temp tables. They need to be persistent but automatically deleted after a certain period of inactivity (no CRUD performed). Is this at all possible?
You can use the SQL Server Agent to Schedule a Job that calls a Stored Procedure that does this work for you. (How to Schedule a Job?)
How do you identify the tables that have not updated since X amount of time ?
Use this Query:
SELECT OBJECT_NAME(OBJECT_ID) AS TableName, last_user_update,
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID('DatabaseName')
AND OBJECT_NAME(OBJECT_ID) LIKE '%%' -- Here is the template name for your tables
AND DATEDIFF(MINUTE, last_user_update, GETDATE()) > 10 -- Last updated more than 10 minutes
Now that you have the tables to be deleted, you can use whatever logic you want to DROP them (Cursor, While, Procedure)
Sure it is. Write it into your program layer.
AUTOMATICALLY - within SQL Server: no. Well, you cold use the agent to start a script regularly.
Tracking what "inactivity" means - your responsibility.
You need save modification date of this table somewhere (for example in the same table or in another special table) and then you can create job, which checks last modification date and then drops the table.

Audit Procedures used on SQL Server DB

I've inherited a database recently which contains thousands of stored procedures and functions, however most of them are deprecated and no longer in use.
I've started adding a piece of code to the stored procedures one at time to notify me if they run, but this process is really quite manual.
Is there any way to start an audit, and see which stored procedures run in the next month or two without adding a piece of code to each stored procedure manually?
Thanks,
Eric
I believe you need to be on SQL Server 2005 SP2 or higher. In prior versions of SQL Server, the OBJECT_NAME function only accepts a parameter for object_id.
Hopefully this should work for you:
SELECT DB_NAME(dest.[dbid]) AS 'databaseName'
, OBJECT_NAME(dest.objectid) AS 'procName'
, MAX(deqs.last_execution_time) AS 'last_execution'
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
WHERE dest.[TEXT] LIKE '%yourTableName%' -- replace
And dest.[dbid] = DB_ID() -- exclude ad-hocs
GROUP BY DB_NAME(dest.[dbid])
, OBJECT_NAME(dest.objectid)
ORDER BY databaseName
, procName
OPTION (MaxDop 1);

Conversion Failed Varchar to Date with TOP and WHERE

I've got a MSSQL 2012 server that holds olders databases (day by day) of my ERP. Simple JOB restores a newest databases from my backup server and removes the oldest one's. It was working fine for few months, but a week ago it started to fail. One of the queries returns: 'Conversion failed when converting date and/or time from character string.'
All database have the same schema for a name 'DATABASE_date' ex.: 'DATABASE_20150224'.
This is the query:
SELECT TOP 1 name
from sys.databases
where name like 'DataBaseName_%'
order by CAST(right(name,8) as DATE)
IF i remove 'TOP 1' it works fine.
SELECT name
from sys.databases
where name like 'DataBaseName_%'
order by CAST(right(name,8) as DATE)
It seems like MSSQL check's all databases on this server (2 new databases of a different app). But why? There's a 'WHERE' cluase and simple select works just fine.
SQL is a declarative language. A database is free to first order the rows and then filter them, or the other way around.
You are relaying on a where clause to filter out rows that would cause an exception in your string manipulation expression. But SQL Server can run the where after the order by.
One approach is bullet-proofing the order by:
order by
case
when name not like 'DataBaseName_%' then name
else CAST(right(name,8) as DATE)
end
Note that even this isn't 100% guaranteed to work. SQL Server could legally evaluate both sides of the case and throw away the second one.

Oracle/SQL Server Database Link Date Format Issue

I have an Oracle hs database link set up between SQL Server 2012 and Oracle 11g.
When Selecting date columns in Oracle from the SQL Server database the date comes through fine but as soon as it has to pass through any function then the date gets cropped from 10 to 5 characters.
For example:
Select Input_Date from schema.table#Database
would return 2000-08-18
Select Len(Input_Date) from schema.table#Database
would return 5
(Select Input_Date from schema.table#Database1
Union
Select Input_Date from schema.table#Database2)
would return 2000-
I am at a loss at what to do, at first the select statement also returned 2000- but then I changed the NLS_DATE_FORMAT parameter which allows a view of the full date in a select statement but has not fixed any of the other issues.
When I select dump(input_date,1016) from schema.table#Database I get
Typ=1, Len=10, CharacterSet=AL16UTF16.
I would really appreciate some help as there seems to be very little information about this online.
Many thanks.

Resources