Wednesday, October 24, 2012

Install .NET Framework 3.5.1 using Powershell

Hi there,
I started to study SQL Server 2012 to take certification exam and I was setting up a lab environment.  In one of the steps the exercise was to install .NET Framework 3.5.1 using powershell.  .NET Framework 3.5.1 is prereq for SQL Server 2012.

To be able to install .NET Framework the I needed to start the session elevated to administrator and then execute the powershell commands.  To accomplish this I took the following steps:

  1. Right click the powershell icon on the taskbar and click on 'Run As Administrator'.
  2. In the powershell window type this command 'Import-Module ServerManager' then hit enter to execute (exclude the single tick before the Import and after the ServerManager)
  3. execute the command 'add-windowsfeature net-framework-core' and hit enter (leave out the single ticks around the command)
Here is the screenshot of the whole process.



HTH,
Bulent

Tuesday, September 25, 2012

PowerShell ExecutionPolicy Access Denied To The Registry Key

Hi all,
I recently accepted an employment offer and now working in Downtown Denver.  Anyhow, I was given a laptop as my workstation.  Since it was a brand new built laptop not everything I needed was installed so I started installing/configuring the software.  One point in time I need to start scripting and I opened the power shell window.  First thing I checked to see the execution policy setting for my new built laptop.  By default a new installation is set to 'Restricted' which does not allow to run a powershell scripts and PowerShell can only be used in interactive mode.  Which is what I expected.  So I started to configure the execution policy.  Here are the steps for how to do it.

Open powershell by clicking start>run and typing 'powershell' (without the ticks) then hit enter.  This will open powershell scripting environment.

1.  Type 'Get-ExecutionPolicy' and hit enter, this will return the execution policy setting.  There are 4 available options and I need to set the execution policy to 'RemoteSigned' to be able to run the scripts I have created and some downloaded from trusted sources.  Here is the link to Microsoft that talks about the policy settings.

In my case, it was set to 'Restricted'

2.  Type 'Set-ExecutionPolicy RemoteSigned' and hit enter.  This is where I got an error message stating that   access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsfot.PowerShell' is denied.  So when this command is executed it tries to set the execution policy for the local machine for all the users.  In my case I only need to set it for my user account not whole machine for all users.

3.  Type 'Set-ExecutionPolicy RemoteSigned -Scope CurrentUser' and hit enter.  No errors.
4.  Type 'Get-ExecutionPolicy' and hit enter and I got 'RemoteSigned' back as the configure setting.

Now I can execute powershell scripts from SQL Server Agent job to do what I need.  All of the above steps have been captured in the screen shot below.

HTH,
Bulent


Thursday, July 26, 2012

VirtualBox Cannot Register The Hard Disk (UUID Already Exists)

I have been using Virtual Box to test some software on a virtual machine as opposed to running the tests on my workstation.  Everything has been working fine while I have a single virtual machine but I had to create a new virtual machine to do some more testing.

I wanted to use the existing virtual machine and not have to install it all over again.  So I copied the folder where my Virtual Machine is stored to another folder.  Then opened the VirtualBox and started to create a new virtual machine and pointed it to the new folder where I copied the contents of the folder for the first Virtual Machine and that's when I got the following error.






Then I started searching the Internet because I knew that the solution must have been available.  I came to find the solution and here is the simple fix for the problem.  We need to open a command prompt and run a command to reset the uuid for the .vdi file where we copied to initiate the second virtual machine.  Here is the steps that need to be done.
   1. Start command prompt (I recommend running it as administrator).
   2. Change your directory to VirtualBox folder.  In my case I am running x64 OS so changed my directory to "C:\Program Files\Oracle\VirtualBox\"
    3. Execute the command to reset the uuid.
        VBOXMANAGE.EXE internalcommands sethduuid <PathOfNewVDI>

The screen shot below is from my workstation which reset the uuid and then I moved on with the VirtualBox and created the new virtual machine.  So in minutes we have a new vm running to do the test.  Simple and fast as long as you know the solution.





HTH,
Bulent

Monday, July 2, 2012

SQL Server Create Identity Field Using Select Into

While working on some data issue I needed to create a backup table on the fly using SELECT INTO statement.  I knew that it was possible but never did it my self.  So it's as simple as defining a column as identity with the data type in the select statement.  Below is statement shows how it's done.

SELECT IDENTITY(INT,1,1) AS RowID,
                *
INTO       dbo.MyTable_Backup
FROM     dbo.MyTable

Hope this helps,
Bulent

Monday, February 20, 2012

Compressing SQL Server Backup Files

Hello Database Professionals,

Starting with SQL Server 2008 Enterprise Edition we have the option of compressing backup files (this includes both BACKUP DATABASE and BACKUP LOG statements which mean not only database backups but log file backups will be compressed) to save disk space and also decrease the duration of the backup and restore operations. The backup compression was an enterprise edition only feature with SQL Server 2008 but with SQL Server 2008 R2 this feature is supported by standard and higher editions. So that was welcome news for me since I support number of SQL Server 2008 R2 Standard Edition.

I have been using T-SQL script to backup databases. The script checks the edition of the SQL Server and then builds the backup command to compress the backup file if it’s enterprise edition or just backups the database if it was a standard edition.

Before the end of 2011 I have completed deploying/upgrading to SQL Server 2008 R2. That meant that my script no longer needed to check the edition of SQL Server 2008 R2 since the compression is already supported in standard and higher editions. So I turned to global configurations and enable the backup compressions. I would like to remind the readers that enabling the backup compression creates additional CPU overhead which depends on you workload might impact your server performance. I suggest that you test your backup process and if necessary using Resource Governor (this is Enterprise Edition only feature) create a low priority compressed backup in a session whose CPU usage is limited by Resource Governor when CPU contention occurs.

Let’s start with checking the backup compression setting for the server by using the script below.

USE master

SELECT *

FROM sys.configurations

WHERE name = 'backup compression default'

ORDER BY name

Let’s check the returned result for the value_in_use column. This shows us the running value curently in effect for this option and is_dynamic column tells us the changes take effect after the RECONFIGURE statement executed. Now it’s time to execute the below script to enable the backup compression since the value_in_use is 0 for the server I am currently working.

USE master

EXEC SP_CONFIGURE 'backup compression default',1

RECONFIGURE

Let’s check the value_in_use by executing the first select statement.

USE master

SELECT *

FROM sys.configurations

WHERE name = 'backup compression default'

Now we should see that the value_in_use is 1 and we don’t need to use the optional keyword COMPRESSION in the backup database command.

By default when backup is compressed checksums are performed to detect media corruptions but if for any reason you need, you can explicitly disable the compression by using NO_COMPRESSION keyword in your backup statement.

I have seen anywhere from 35% to 80% compression ration and backup duration decrease from several hours to 30-45 minutes for the databases I administor. Your mileage will vary and you should TEST, TEST, TEST and deploy your changes for your environments. Here is the link to find out more about backup database command in MSDN.

HTH,

Bulent

Friday, February 3, 2012

Dropping Multiple SQL Server Objects in Single Line

As humans we try to find a way to work faster and efficient. As data professionals, typing less probably is another thing we want. My SQL Server tip today is about dropping multiple objects (tables, views, stored procedures, and even databases) in single drop statement. This is powerful but can be dangerous in production so please use caution. Here is a script that creates couple of tables and then drops both tables in single drop statement.

Sincerely,

Bulent

-- CREATE TABLES

USE tempdb

GO

CREATE TABLE dbo.TableT1 (t1c1 TINYINT)

CREATE TABLE dbo.TableT2 (t2c1 TINYINT)

GO

INSERT INTO dbo.TableT1 VALUES(1)

INSERT INTO dbo.TableT2 VALUES(2)

GO

-- CHECK THE TABLES CREATED

SELECT *

FROM sys.tables

WHERE name LIKE 'TableT_'

GO

-- DROP BOTH TABLES IN SINGLE DROP STATEMENT

DROP TABLE dbo.TableT1, dbo.TableT2

GO

-- CHECK THE TABLES DROPPED

SELECT *

FROM sys.tables

WHERE name LIKE 'TableT_'

GO

Friday, January 27, 2012

Cycling SQL Server Error Log

I have a daily check list that I go through everyday. And checking the SQL Server error log is one item on the list. Depends on how your server is configured SQL Server logs informational and error messages to the log file. By default your server is configured to have 6 log files that it keeps and when the SQL Server Service starts it removes the oldest log file. In the meantime if your server is up for a long time the information in that log file just keeps growing and makes the log file hard to open from remote workstation.

In the environments that I support I change the configuration so that I keep more than 6 files. I set up to store 99 files (which is the max allowed files for the SQL Server error log). Then I create a job that runs every night right after midnight. This way when I come in every morning there is a brand new log file and since the daily log files are much smaller it makes the file easy to open and check. I use the script below to change the number of log files (note you can do this using SSMS GUI and just make a right click on SQL Server Logs under Management folder than click on Configure and change the value to what you need). After the change using second script I create SQL Server Agent Job that is scheduled to run right after midnight to cycle the error log. This make the daily task of checking the error logs easier (at least for me). Use the scripts below in a test environment and once you find out it could add some value to your daily tasks you could use it in your production environment.

HTH,
Bulent

Script 1:
This changes the number of log files stored to a value you set at the end and uses extended stored procedure to update the registry. Remember this can be done through GUI but it does executed the same in the background.

USE [master]
GO
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', REG_DWORD, 60
GO



Script 2:
This script creates a job (make sure you sql server agent is running) and schedules it to run at 12:00:01 am everyday.

USE [msdb]
GO
/****** Object: Job [A DBA SQL Server Error Log Cycle] Script Date: 01/27/2012 14:01:38 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object: JobCategory [Database Maintenance] Script Date: 01/27/2012 14:01:38 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'Database Maintenance' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'A DBA SQL Server Error Log Cycle',
@enabled=1,
@notify_level_eventlog=2,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Cycle sql serve error log and create a new error log file',
@category_name=N'Database Maintenance',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object: Step [Cycle Error Log] Script Date: 01/27/2012 14:01:38 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Cycle Error Log',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXEC sp_cycle_errorlog ;
',
@database_name=N'master',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'Cycle Error Log',
@enabled=1,
@freq_type=4,
@freq_interval=1,
@freq_subday_type=1,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=0,
@active_start_date=20111013,
@active_end_date=99991231,
@active_start_time=1,
@active_end_time=235959

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
GO

Friday, January 20, 2012

SSRS 2008 Transport Error Code 0x800ccc15

Hello all,

I received and email stating that a user did not receive the report from SSRS that he was subscribed to in the last couple of days. When I start looking into the report in the subscription tab of the report I saw the message below.

Failure sending mail: The message could not be sent to the SMTP server. The transport error code was 0x800ccc15. The server response was not available

I tried to open the report and had no problem running the report manually. Then I update the schedule of the report to see if the scheduled sql server agent job is updated as well. Then I looked at the jobs in the server hosting ReportServer database and found the corresponding job with that timed subscription and verified that the execution time of the job is updated with what I did using SSRS portal (In the SQL Server Agent Jobs the name of the jobs for SSRS are given using a system generated GUID and if you don't know the job it's hard to locate since there may be many of them, in my case there were only 8 jobs and I knew which job I need to check once I made the change. However in future blog I will post about this in little more detail). I waited for couple of minutes and saw that the job executed in SQL Server Agent hosting ReportServer database. However still saw the same error message.

I remote into the SSRS server to look into to the problem locally. As soon as I logged in I saw a red icon on the task bar coming from McAfee. I remember that I had to change the configuration of the McAfee to allow database mail to work couple weeks ago. I opened the log and found that the log event below.
1/19/2012 2:30:30 PM Blocked by port blocking rule C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\bin\ReportingServicesService.exe Anti-virus Standard Protection:Prevent mass mailing worms from sending mail 192.168.162.162:250

That is when I knew what was wrong. The McAfee ePO policy change forced to server so that processes that need to send email has to be excluded in the Prevent Mass Mailing Worms section. I talked to sysadmin who administers the ePO policy to exclude the ReportingServicesService.exe and push the policy again to the server. Within a minute policy was in effect. I update the report subscription to 3 minutes later and waited for the mail to arrive with the report attached. After 3 minutes voila, I received the email and solved the problem. In my case it was as simple as adding the process to exclusion list to send SMTP emails.

HTH,
Bulent

Thursday, January 12, 2012

SQL Function QUOTENAME()

Hello all,

I support third party software databases at work. During the implementation of the application it needed to create a database to store the data. However the application created a database with a name that does not follow the rules for the format of identifiers. In my case we ended up with a database name '20120101_Survey'.

On the same server I have a custom built script that backups up all the databases at night. However, following the database creation my backup process failed and I got an alert about the process. Further looking into the problem I found out that there was a problem with the syntax. As soon as I see the statement I knew what the problem was but never thought about it while deploying the application and database. To keep the story short I used the SQL Server function called QUOTENAME() to fix the problem. Using the function in my custom script help me return the database names with delimiters so that backup process completes without error. Since then I have been using the function with all the object names. This simple function can prevent some headaches if a DBA needs to support 3rd party databases (SharePoint is also a good example because the SharePoint database names don't follow the rules of the identifier format). Here is the link to the msdn and below is simple statement that returns all the databases in your system with delimiters.

SELECT QUOTENAME(name) AS DelimitedDbName
FROM sys.databases

HTH,
Bulent

Enhanced by Zemanta