13

I need to exec a powershell script that exec a SQL script to create a database. Based on my knowledge I exec the powershell command in this way:

Init.ps1

$DATABASEFILENAME = "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008INSTANCE\MSSQL\DATA\myDB.mdf"
$DATABASELOGNAME = "C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008INSTANCE\MSSQL\DATA\myDB_log.ldf"
$DBUSEROWNER = "domain\spsetup"

CreateDatabase.ps1

 try {
        $createDatabaseScript = ($scriptsFolder,$eachRelease,$DeployEnvironment,"Config" -join "\") + "\JM SiteRequest Database.sql"
        $sqlVariable = "DATABASEFILENAME = '$DATABASEFILENAME'", "DATABASELOGNAME = '$DATABASELOGNAME'", "DBUSEROWNER = '$DBUSEROWNER'"

        Invoke-Sqlcmd -ServerInstance "$MySQLServer" -InputFile "$createDatabaseScript" -ErrorAction Stop -Variable $sqlVariable
}
catch [Exception] {
        Write-Error "Database error: $_.Exception"
}

SQL script

CREATE DATABASE [SiteRequestDB] ON  PRIMARY
( NAME = N'SiteRequestDB', FILENAME = N'$(DATABASEFILENAME)' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON 
( NAME = N'SiteRequestDB_log', FILENAME = N'$(DATABASELOGNAME)' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

I updated the $sqlVariable as @Chad Miller suggested. So the problem was there. Now I got this error: Creating the database error: Database error: An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name. The label 'C' has already been declared. Label names must be unique within a query batch or stored procedure..Exception.Exception

5
  • 2
    Define "doesn't work". How exactly is the result you get different from the result you expect? Commented May 20, 2013 at 18:11
  • Can you add some hard coded values. "DATABASEFILENAME = MyFileName", "DATABASELOGNAME = 'sa'", "DBUSEROWNER = 'myUser'" as a temp test? Commented May 20, 2013 at 18:27
  • @granadaCoder yes I can, I will do that Commented May 21, 2013 at 7:49
  • 1
    Try taking the spaces out. IIRC, I have used MYVARIABLENAME=Abc123 (no spaces). Commented May 21, 2013 at 13:05
  • See edits. I tested your script on my machine and found I had to remove single quotes or these are included in variable. Commented May 21, 2013 at 17:51

3 Answers 3

13

The Variable parameter for the Invoke-Sqlcmd cmdlet is picky. Do not include spaces before or after the variable assignment.

$sqlVariable = "DATABASEFILENAME='$DATABASEFILENAME'", "DATABASELOGNAME='$DATABASELOGNAME'", "DBUSEROWNER='$DBUSEROWNER'"

Also you need remove single quotes from variables:

$sqlVariable = "DATABASEFILENAME=$DATABASEFILENAME", "DATABASELOGNAME=$DATABASELOGNAME", "DBUSEROWNER=$DBUSEROWNER"
4
  • You are right but now I got the following error Creating the database error: Database error: An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name. The label 'C' has already been declared. Label names must be unique within a query batch or stored procedure..Exception.Exception Commented May 21, 2013 at 7:52
  • 2
    In MDSN's document, the example given there has single quote and spaces, why is that? $MyArray = "MyVar1 = 'String1'", "MyVar2 = 'String2'" Invoke-Sqlcmd -Query "SELECT $(MyVar1) AS Var1, $(MyVar2) AS Var2;" -Variable $MyArray
    – kate1138
    Commented Feb 2, 2015 at 9:35
  • If you are mixing this with azdevops variables do NOT include a period in your variable name like so: $(Category.Thing.Name). It will NOT parse. Commented Sep 2, 2020 at 21:47
  • This answer is actually not correct and would not solve the problem. @kate1138 points out the command variable is ok with spaces around the equal sign. The issue was the single quotes in the variable value and the single quotes in the sql script. Correct answer posted below.
    – Jim
    Commented Aug 23, 2022 at 15:15
1

I know this is old, there is not any real good explanations/examples on this so I am posting this answer.

The error is being generated from the TSQL script having two single quotes around the values for the data file name and log file name after the command variable substitution has taken place. This is due to the variable values containing single quotes and the TSQL script usage of the variables being enclosed in single quotes too. Command variables are not that picky, the parser doesn't know how to handle embedded spaces in the definition. You were correct in placing the single quotes in the string variables, however keep in mind the parser replaces the variable with exactly what was defined in the variable.

Your end result script file names had two single quotes together on either side of the file name. i.e.

"DATABASEFILENAME = '$DATABASEFILENAME'"

placed in the script would result in the following after substitution took place

FILENAME = N''C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008INSTANCE\MSSQL\DATA\myDB.mdf''

To fix what you posted:

SQL Script

CREATE DATABASE [SiteRequestDB] ON  PRIMARY
( NAME = N'SiteRequestDB', FILENAME = N$(DATABASEFILENAME) , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON 
( NAME = N'SiteRequestDB_log', FILENAME = N$(DATABASELOGNAME) , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
0

First of all, specify the error message if any.

Also, there is no need to define log and data file locations, try to use the snippet below, it works for me in many projects.

$sqlServerName = "%your SQL server instance%" #for example, ".\SQLEXPRESS"
$file = "C:\yourScript.sql"
$database = "testDatabaseName"

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") $sqlServerName
Invoke-SqlCmd -inputfile $file -serverinstance $server -database $database
1
  • 2
    Although not required it's good practice to separate database files from log files. Commented May 20, 2013 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.