0

I have a script that creates a sql localdb (2014), creates a table and puts some data into it. If I run this script in SSMS against a full SQL server 2014 instance, it completes fine and all the data in the table looks as I'd expect it to.

However, when I run this via SQLCMD or a Visual Studio app, the £ and € in the strings are interpreted and stored as ? in the database.

I've checked the collation, and tried forcing both the database and/or the columns in question to use the same collation as my working server, but it's still not storing the £ and € correctly.

Any Ideas anyone?

This is a cutdown version of the code, but it hopefully gets the point across:

IF (EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE ('[' + name + ']' = 'Hestia' OR name = 'Hestia'))) 
BEGIN 
  ALTER DATABASE [Hestia] SET SINGLE_USER WITH ROLLBACK Immediate
  DROP DATABASE [Hestia]
END
GO
CREATE DATABASE [Hestia] 
--Collate Latin1_General_CI_AS
GO
ALTER DATABASE [Hestia] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [Hestia].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [Hestia] SET ANSI_NULL_DEFAULT ON 
GO
ALTER DATABASE [Hestia] SET ANSI_NULLS ON 
GO
ALTER DATABASE [Hestia] SET ANSI_PADDING ON 
GO
ALTER DATABASE [Hestia] SET ANSI_WARNINGS ON 
GO
ALTER DATABASE [Hestia] SET ARITHABORT ON 
GO
ALTER DATABASE [Hestia] SET AUTO_CLOSE OFF 
GO
ALTER DATABASE [Hestia] SET AUTO_CREATE_STATISTICS ON 
GO
ALTER DATABASE [Hestia] SET AUTO_SHRINK OFF 
GO
ALTER DATABASE [Hestia] SET AUTO_UPDATE_STATISTICS ON 
GO
ALTER DATABASE [Hestia] SET CURSOR_CLOSE_ON_COMMIT OFF 
GO
ALTER DATABASE [Hestia] SET CURSOR_DEFAULT  LOCAL 
GO
ALTER DATABASE [Hestia] SET CONCAT_NULL_YIELDS_NULL ON 
GO
ALTER DATABASE [Hestia] SET NUMERIC_ROUNDABORT OFF 
GO
ALTER DATABASE [Hestia] SET QUOTED_IDENTIFIER ON 
GO
ALTER DATABASE [Hestia] SET RECURSIVE_TRIGGERS OFF 
GO
ALTER DATABASE [Hestia] SET  DISABLE_BROKER 
GO
ALTER DATABASE [Hestia] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
GO
ALTER DATABASE [Hestia] SET DATE_CORRELATION_OPTIMIZATION OFF 
GO
ALTER DATABASE [Hestia] SET TRUSTWORTHY OFF 
GO
ALTER DATABASE [Hestia] SET ALLOW_SNAPSHOT_ISOLATION OFF 
GO
ALTER DATABASE [Hestia] SET PARAMETERIZATION SIMPLE 
GO
ALTER DATABASE [Hestia] SET READ_COMMITTED_SNAPSHOT OFF 
GO
ALTER DATABASE [Hestia] SET HONOR_BROKER_PRIORITY OFF 
GO
ALTER DATABASE [Hestia] SET RECOVERY FULL 
GO
ALTER DATABASE [Hestia] SET  MULTI_USER 
GO
ALTER DATABASE [Hestia] SET PAGE_VERIFY NONE  
GO
ALTER DATABASE [Hestia] SET DB_CHAINING OFF 
GO
CREATE TABLE [dbo].[Denomination](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [Currency] [nvarchar](50) NOT NULL,
    [Value] [decimal](18, 4) NOT NULL
 CONSTRAINT [PK_Denominations] PRIMARY KEY CLUSTERED 
(
    [DenominationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO [dbo].[Denomination] ([Id], [Name], [Currency], [Value]) VALUES (7, N'£1', N'GBP', 1.0000)
INSERT INTO [dbo].[Denomination] ([Id], [Name], [Currency], [Value]) VALUES (8, N'£2', N'GBP', 2.0000)
INSERT INTO [dbo].[Denomination] ([Id], [Name], [Currency], [Value]) VALUES (9, N'£5', N'GBP', 5.0000)
INSERT INTO [dbo].[Denomination] ([Id], [Name], [Currency], [Value]) VALUES (25, N'€1', N'EUR', 1.0000)
INSERT INTO [dbo].[Denomination] ([Id], [Name], [Currency], [Value]) VALUES (26, N'€2', N'EUR', 2.0000)
INSERT INTO [dbo].[Denomination] ([Id], [Name], [Currency], [Value]) VALUES (27, N'€5', N'EUR', 5.0000)

and app code:

public static ActionResult CreateDatabase(Session session)
        {
          ActionResult result = ActionResult.NotExecuted;
          session.Log("Begin Create Hestia Database");
          try
          {
            //System.Diagnostics.Debugger.Launch();

            ISqlLocalDbApi localDb = new SqlLocalDbApiWrapper();
            if (localDb.IsLocalDBInstalled())
            {
              ISqlLocalDbProvider provider = new SqlLocalDbProvider();
              ISqlLocalDbInstance instance = provider.GetOrCreateInstance(@"MyLocalDB");

              // Check it's running
              if (!instance.GetInstanceInfo().IsRunning)
              {
                session.Log("Starting MyLocalDB instance");
                instance.Start();
              }


              using (SqlConnection connection = instance.CreateConnection())
              {
                connection.Open();

                try
                {
                  // These two scripts are linked as content in our project
                  // So WiX bundles them into the temp folder we run in
                  string createScript = File.ReadAllText(@"1. Create.sql");
                  string dataScript = File.ReadAllText(@"2. StaticData.sql");

                  // Use a SMO server connection because it's happy
                  // with scripts containing GOs etc.
                  Server server = new Server(new ServerConnection(connection));

                  // Execute both scripts
                  session.Log("Executing create script");
                  server.ConnectionContext.ExecuteNonQuery(createScript);
                  session.Log("Executed create script");
                  session.Log("Executing static data script");
                  server.ConnectionContext.ExecuteNonQuery(dataScript);
                  session.Log("Executed static data script");
                }
                finally
                {
                  connection.Close();
                }
              }

            }
            else
            {
              session.Log("LocalDB Not Installed");
            }

            result = ActionResult.Success;
          }
          catch (Exception e)
          {
            System.Diagnostics.Debugger.Launch();
            var innerex = e.InnerException;
            var innerex2 = e.InnerException.InnerException == null ? String.Empty : e.InnerException.InnerException.ToString();
            session.Log(string.Format("Error: {0}", e.Message + innerex + innerex2));
            result = ActionResult.Failure;
          }

          session.Log("End Create MyLocalDB Database");
          return result;
        }
user692942
  • 16,398
  • 7
  • 76
  • 175
Xev
  • 11
  • 2
  • 1
    Ideally we need to see the SQLCMD or "Visual Studio app" code you use to call the script. As you said the script works fine from SSMS. If it works from SSMS what makes you think there is a problem with the database? The issue will reside with the method being used to execute the script. – user692942 Mar 07 '16 at 14:51
  • When calling [`sqlcmd` utility](https://msdn.microsoft.com/en-us/library/ms162773(v=sql.120).aspx) do you pass the `-f` switch to specify the input and output code pages? – user692942 Mar 07 '16 at 14:56
  • I've added the app code to OP. Hope it helps. – Xev Mar 07 '16 at 15:06
  • 1
    Is the script file saved as UTF8 or some non-Unicode codepage? If you copy an ASCII file to a system with an incompatible codepage, it doesn't matter whether you use `Ν'€1'` or not, the text will be mangled when reading the text. – Panagiotis Kanavos Mar 07 '16 at 15:20
  • Its saved as a .sql file. – Xev Mar 07 '16 at 15:24
  • Yes but Panagiotis is asking what is the encoding of the script file when it was saved? The thing is [`File.ReadAllText(String)`](https://msdn.microsoft.com/en-us/library/ms143368(v=vs.110).aspx) attempts to automatically detect the encoding if that fails or you have an encoding mismatch *(with how the file was saved)* then you will get these types of issues. You are also returning a `string` data type which will need to be converted to UTF-8 *(See [How can I transform string to UTF-8 in C#?](http://stackoverflow.com/a/14057684/692942))*. – user692942 Mar 07 '16 at 15:30
  • Looks like its UTF-8, having opened it in notepad++ and checked the encoding there. – Xev Mar 07 '16 at 15:37
  • The .SQL script file had somehow changed the encoding of the £ and € characters and thus they couldn't be read during the insert into the database. This was only apparent when opening the file in notepad++, it looked fine in SSMS. – Xev Mar 08 '16 at 09:25

0 Answers0