SQL Server: Can a stored procedure cause a memory leak?

Yes, a memory leak is possible if you forget to call sp_xml_removedocument (for each matching sp_xml_preparedocument):

A parsed document is stored in the internal cache of SQL Server. The MSXML parser (Msxmlsql.dll) uses one-eighth the total memory available for SQL Server. To avoid running out of memory, run sp_xml_removedocument to free up the memory.

Example usage:

DECLARE @xml_text VARCHAR(4000), @i INT
SELECT @xml_text = '... some valid xml ...'

EXEC sp_xml_preparedocument @i OUTPUT, @xml_text

....

EXEC sp_xml_removedocument @i

Another form of memory leak is forgetting to both close and deallocate a cursor:

DECLARE c CURSOR   
  LOCAL STATIC FORWARD_ONLY READ_ONLY   
  FOR SELECT ...

....
CLOSE c; 
DEALLOCATE c;

Just for the record, even though I always like to see an explicit CLOSE and DEALLOCATE for cursors:

LOCAL cursors are implicitly de-allocated when the stored procedure, trigger, or batch in which they were created terminates, unless the cursor has been passed back as a parameter. The LOCAL cursor will then be implicitly de-allocated when the parameter or variable referencing the cursor in the code that called the procedure goes out scope.

Ref.

[Note: I rarely use cursors. Wherever possible and appropriate, I always try to do it the set-based way]

SQL Server: A Gotcha with Disabling/Enabling Foreign Keys and Check Constraints

When loading a large dataset, you can significantly reduce the load time by disabling foreign keys and check constraints during the load process (and ETL’s often perform data integrity checks anyway).  This is commonly done with large data warehouses where entire dimensions are reloaded every day. When the load is complete, they are re-enabled, and SQL Server will ensure that the keys and constraints are honoured.  That is, as long as you re-enable them correctly. And due to the syntax, it is possible to re-enable them without forcing a re-validation of the data (in which case, they have the status of ‘not-trusted’).

Not only does this mean that referential integrity is not being enforced (which is a bad thing!), but it can also have a negative performance impact on queries, because SQL Server won’t use un-trusted constraints in order to build execution plans.

Run this TSQL to check if you have any foreign keys or check constraints that are not trusted:

-- Must be run in the database being examined:
USE MyDB
-- non trusted foreign keys
Select '[' + s.name + '].[' + o.name + '].[' + fk.name + ']' AS keyname 
from sys.foreign_keys fk 
INNER JOIN sys.objects o ON fk.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE fk.is_not_trusted = 1 AND fk.is_not_for_replication = 0 AND fk.is_disabled = 0

-- non trusted check constraints
Select '[' + s.name + '].[' + o.name + '].[' + c.name + ']' AS constraintname
from sys.check_constraints c 
INNER JOIN sys.objects o ON c.parent_object_id = o.object_id 
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id 
WHERE c.is_not_trusted = 1 AND c.is_not_for_replication = 0 AND c.is_disabled = 0
GO

To ensure that SQL Server not only re-enables a constraint, but also rechecks all the data, you have to specify the CHECK keyword twice:

ALTER TABLE MyTable 
    WITH CHECK CHECK CONSTRAINT MyConstraint
         ^^    ^^

Note: If the table is very large, you might want to perform this during scheduled maintenance.

 

YOW! Night Perth – Julian Boot – Thurs, Oct 18: 6pm

Join us for YOW! Night to hear “Design Eye for a Dev Guy” by Julian Boot as he describes what developers need to do to contribute to the design of a good UI: a crash course on visual design for developers. Learn how to ensure you have an Agile team that supports and enables good UI design. Julian is well known in Australia as a leader in the software community and international Agile Development speaker. Please register here: http://www.eventbrite.com/event/4499698720

TOPIC: “Design Eye for a Dev Guy” with Julian Boot
DATE: Thursday, 18th October, 6pm – 7:30pm
VENUE: Enex 100 Seminar Room, Level 3, 100 St Georges Terrace, Perth
COST: Free. All welcome.

Seats are limited. Please note the 6pm start time rather than the usual 5:30pm start (due to room availability).

Find Max Value of Multiple Columns

Nothing new, but a nice trick to find the maximum value of a number of columns within a row, due to Louis Davidson (via Simon Sabin). It uses the fact that a sub-query can reference columns from the main rowset.

select 
WorkOrderId,
(select max(DateValue)
from (select StartDate as DateValue
union all
select EndDate
union all
select DueDate
union all
select ModifiedDate) as DateCols) as MaxDate,
StartDate,
EndDate,
DueDate,
ModifiedDate
from
Production.WorkOrder

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

SQL Server Agent Job History Statistics

It’s sometimes useful to know how long on average each SQL Server Agent Job takes and what the variation in running time is. You might want to increase how much Agent job history that SQL Server retains (the defaults are quite low).

-- Agent job history over all runs in retained in history
declare @tmp_sp_help_jobhistory table
(
instance_id int null,
job_id uniqueidentifier null,
job_name sysname null,
step_id int null,
step_name sysname null,
sql_message_id int null,
sql_severity int null,
message nvarchar(4000) null,
run_status int null,
run_date int null,
run_time int null,
run_duration int null,
operator_emailed sysname null,
operator_netsent sysname null,
operator_paged sysname null,
retries_attempted int null,
server sysname null
)

insert into @tmp_sp_help_jobhistory
exec msdb.dbo.sp_help_jobhistory @mode='FULL'

;with cteRuns as
(
SELECT
tshj.job_name AS [JobName],
convert(datetime,
stuff(stuff(cast(tshj.run_date as nchar(8)), 7, 0, '-'), 5, 0, '-') + N' ' +
stuff(stuff(substring(cast(1000000 + tshj.run_time as nchar(7)), 2, 6), 5, 0, ':'), 3, 0, ':'),
120) AS [RunDate],
( run_duration % 100 + ((run_duration / 100) % 100) * 60 + ((run_duration / 10000) % 100) * 3600 +
((run_duration / 1000000) % 100) * 86400 )
AS [RunDurationSeconds]
FROM @tmp_sp_help_jobhistory as tshj
where step_ID = 0 and run_status = 1
)
, cteAggRuns as
(
SELECT
JobName,
MAX(RunDate) AS LastRunDate,
AVG(RunDurationSeconds) AS [AverageRunDurationSeconds],
Min(RunDurationSeconds) AS [MinDurationAverageSeconds],
Max(RunDurationSeconds) AS [MaxRunDurationSeconds],
COUNT(jobname) as NumRunsInHistory,
sqrt(var(RunDurationSeconds)) AS [stdRunDurationSeconds]
FROM cteRuns
group by JobName

)
select
JobName,
LastRunDate,
AverageRunDurationSeconds,
MinDurationAverageSeconds,
MaxRunDurationSeconds,
NumRunsInHistory,
stdRunDurationSeconds
from cteAggRuns
ORDER BY JobName

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Similarly you might want to get this information for just the last 5 runs say (for instance, when you’ve altered jobs):

declare @tmp_sp_help_jobhistory table
(
instance_id int null,
job_id uniqueidentifier null,
job_name sysname null,
step_id int null,
step_name sysname null,
sql_message_id int null,
sql_severity int null,
message nvarchar(4000) null,
run_status int null,
run_date int null,
run_time int null,
run_duration int null,
operator_emailed sysname null,
operator_netsent sysname null,
operator_paged sysname null,
retries_attempted int null,
server sysname null
)

insert into @tmp_sp_help_jobhistory
exec msdb.dbo.sp_help_jobhistory @mode='FULL'

;with cteRuns as
(
SELECT
job_name AS [JobName],
( run_duration % 100 + ((run_duration / 100) % 100) * 60 + ((run_duration / 10000) % 100) * 3600 +
((run_duration / 1000000) % 100) * 86400 )
AS [RunDurationSeconds],
convert(datetime,
stuff(stuff(cast(run_date as nchar(8)), 7, 0, '-'), 5, 0, '-') + N' ' +
stuff(stuff(substring(cast(1000000 + run_time as nchar(7)), 2, 6), 5, 0, ':'), 3, 0, ':'),
120) AS [RunDate]
FROM @tmp_sp_help_jobhistory
where step_ID = 0 and run_status = 1
)
, cteLast5Runs as
(
SELECT
ROW_NUMBER() over (partition by JobName order by RunDate DESC) as rownum,
JobName,
RunDurationSeconds,
RunDate
FROM cteRuns
)
SELECT
JobName,
AVG(RunDurationSeconds) AS [AverageRunDurationSeconds],
Min(RunDurationSeconds) AS [MinDurationAverageSeconds],
Max(RunDurationSeconds) AS [MaxRunDurationSeconds],
COUNT(jobname) as NumRunsInHistory,
sqrt(var(RunDurationSeconds)) AS [stdRunDurationSeconds]
FROM cteLast5Runs
where rownum between 1 AND 5
group by JobName
ORDER BY JobName

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

How to enable Code Analysis in Visual Studio 2010 Professional?

If you only have the Pro version of VS2010, you can use FxCop Integrator or you can Download FxCop 1.36 and add following command into the post-build event:

    "(ProgramFiles)\Microsoft FxCop 1.36\FxCopCmd.exe"</span> /c /p:<span class="str">"(ProjectDir)\FxCop(ConfigurationName).FxCop"</span> /consolexsl:<span class="str">"(ProgramFiles)\Microsoft FxCop 1.36\Xml\VSConsoleOutput.xsl"

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/white-space: pre;/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

as mentioned here: http://stackoverflow.com/questions/2833608/how-to-enable-code-analysis-in-visual-studio-2010-professional

Reminder: Perth .NET User Group: Thurs 7th June 5:30pm – 7pm:

A quick reminder that Dr Scott Hollier will be presenting tonight (Thurs, 7th June) on Web and Application Accessibility. Come along to hear Dr Scott Hollier from Media Access Australia explain how you can make sure your web development complies with the government’s accessibility requirements, learn how people with disabilities are likely to interact with your work and how the likely impact of future Web standards.

  • TOPIC: Web and Application Accessibility with Dr Scott Hollier
  • DATE:   Thurs June 7th, 5:30pm – 7:00pm
  • VENUE: Enex 100 Seminar Room, Level 3, 100 St Georges Terrace, Perth
  • COST:   Free. All welcome
  • Time to Change Your LinkedIn Password?….

    More than 6 million LinkedIn passwords stolen:

    http://money.cnn.com/2012/06/06/technology/linkedin-password-hack/index.htm?hpt=hp_t3

    http://www.pcadvisor.co.uk/how-to/security/3362143/how-to-change-a-linkedin-password/

    Loved this bit:

    Countless passwords on the list contain the word “linkedin.”

    How to change a LinkedIn password

    Log into LinkedIn and click your name in the top right of the LinkedIn page.

    Select “Settings” from the dropdown and choose “Change” next to Password.

    Perth .NET User Group Meeting, Thurs June 7th: Web and Application Accessibility with Dr. Scott Hollier

    Join us at the Perth .NET user group, Thurs June 7th where Dr. Scott Hollier will present on Web and Application Accessibility. The Federal government’s National Transition Strategy and accompanying state government policies now require that all government websites meet accessibility criteria.  Come along to hear Dr Scott Hollier from Media Access Australia explain how you can make sure your web development complies with the government’s accessibility requirements, learn how people with disabilities are likely to interact with your work and how the likely impact of future Web standards.

  • TOPIC:  Web and Application Accessibility with Dr. Scott Hollier 
  • DATE:   Thurs June 7th, 5:30pm – 7:00pm
  • VENUE: Enex 100 Seminar Room, Level 3, 100 St Georges Terrace, Perth
  • COST:   Free. All welcome

    Scott Hollier is a Project Manager and the Western Australia Manager for Media Access Australia, a not-for-profit, public benevolent institution. Scott’s work focuses on making computers and Internet-related technologies accessible to people with
    disabilities. Scott also represents MAA on the Advisory Committee of the World Wide Web Consortium (W3C), the organisation primarily responsible for developing and promoting access to media through technology for people with disabilities.

    Scott has completed a PhD titled ‘The Disability Divide: an examination into the needs of computing and Internet-related technologies on people who are blind or vision impaired’, and has a background in Computer Science and a wealth of experience in both the information technology and not-for-profit sectors. Scott is legally blind and as such understands the importance of access at a personal level.