From 78c752f7437a7711de233e675e4da2ea455ddd98 Mon Sep 17 00:00:00 2001 From: Keys Date: Fri, 19 Oct 2018 14:49:34 +0100 Subject: [PATCH 1/3] porting the C# base example to F# --- samples/tutorials/f#/README.md | 56 +++++++++++ .../tutorials/f#/SqlServerSample/Program.fs | 96 +++++++++++++++++++ .../f#/SqlServerSample/SqlServerSample.fsproj | 16 ++++ 3 files changed, 168 insertions(+) create mode 100644 samples/tutorials/f#/README.md create mode 100644 samples/tutorials/f#/SqlServerSample/Program.fs create mode 100644 samples/tutorials/f#/SqlServerSample/SqlServerSample.fsproj diff --git a/samples/tutorials/f#/README.md b/samples/tutorials/f#/README.md new file mode 100644 index 00000000..daa36dd6 --- /dev/null +++ b/samples/tutorials/f#/README.md @@ -0,0 +1,56 @@ +# Get started with SQL Server and F# + +Get started quickly with developing applications in F# on any OS with SQL Server + + +### Contents + +[About this sample](#about-this-sample)
+[Before you begin](#before-you-begin)
+[Run this sample](#run-this-sample)
+[Disclaimers](#disclaimers)
+[Related links](#related-links)
+ + + + +## About this sample + +- **Applies to:** SQL Server 2016 (or higher) +- **Workload:** + - CRUD with .NET + - Performance improvements with Columnstore +- **Programming Language:** F# +- **Authors:** keyset + + + +## Before you begin + +To run this sample, you need the following prerequisites. + +**Software prerequisites:** + +1. SQL Server 2016 (or higher) +2. [.NET Core](https://www.microsoft.com/net/download) v2.1 or higher + +## Run this sample + +1. In Visual Studio, open the Program.fs file and update the connection string username and password with your own. + +2. Open a terminal in the desired sample subfolder and execute: + ``` + dotnet run + ``` + + + +## Disclaimers +The scripts and this guide are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them. + + + +## Related Links + +For more information, see these articles: +* To see more getting started tutorials, visit our [tutorials page](https://www.microsoft.com/en-us/sql-server/developer-get-started/) diff --git a/samples/tutorials/f#/SqlServerSample/Program.fs b/samples/tutorials/f#/SqlServerSample/Program.fs new file mode 100644 index 00000000..9501b963 --- /dev/null +++ b/samples/tutorials/f#/SqlServerSample/Program.fs @@ -0,0 +1,96 @@ +// Learn more about F# at http://fsharp.org + +open System +open System.Data.SqlClient + +[] +let main argv = + printfn "Connect to SQL Server and demo Create, Read, Update and Delete operations." + let builder = new SqlConnectionStringBuilder() + builder.DataSource <- "localhost" + builder.UserID <- "sa" + builder.Password <- "your_password" + builder.InitialCatalog <- "master" + + printf "Connecting to SQL Server ... " + use connection = new SqlConnection(builder.ConnectionString) + + try + connection.Open() + printfn "Done." + + // Create a sample database + printf "Dropping and creating database 'FSharpSampleDB' ... " + let sql = "DROP DATABASE IF EXISTS [FSharpSampleDB]; CREATE DATABASE [FSharpSampleDB]" + use command = new SqlCommand(sql, connection) + command.ExecuteNonQuery() |> ignore + printfn "Done." + + // Create a Table and insert some sample data + printf "Creating sample table with data, press any key to continue..." + Console.ReadKey(true) |> ignore + let sql = " + USE FSharpSampleDB; + CREATE TABLE Employees ( + Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, + Name NVARCHAR(50), + Location NVARCHAR(50) + ); + INSERT INTO Employees (Name, Location) VALUES + (N'Tom', N'United States'), + (N'Krzysztof', N'Poland'), + (N'Isaac', N'Germany'); " + + use command = new SqlCommand(sql, connection) + command.ExecuteNonQuery() |> ignore + printfn "Done." + + // INSERT demo + printf "Inserting a new row into table, press any key to continue... " + Console.ReadKey(true) |> ignore + let sql = " + INSERT Employees (Name, Location) + VALUES (@name, @location);" + use command = new SqlCommand(sql, connection) + command.Parameters.AddWithValue("@name", "Don") |> ignore + command.Parameters.AddWithValue("@location", "United Kingdom") |> ignore + let rowsAffected = command.ExecuteNonQuery() + printfn "%i row(s) inserted" rowsAffected + + // UPDATE demo + let userToUpdate = "Tom"; + printf "Updating 'Location' for user '%s', press any key to continue... " userToUpdate + Console.ReadKey(true) |> ignore + let sql = "UPDATE Employees SET Location = N'United Kingdom' WHERE Name = @name" + use command = new SqlCommand(sql, connection) + command.Parameters.AddWithValue("@name", userToUpdate) |> ignore + let rowsAffected = command.ExecuteNonQuery() + printfn "%i row(s) updated" rowsAffected + + // DELETE demo + let userToDelete = "Don"; + printf "Deleting user '%s', press any key to continue... " userToDelete + Console.ReadKey(true) |> ignore + let sql = "DELETE FROM Employees WHERE Name = @name;" + use command = new SqlCommand(sql, connection) + command.Parameters.AddWithValue("@name", userToDelete) |> ignore + let rowsAffected = command.ExecuteNonQuery() + printfn "%i row(s) deleted" rowsAffected + + // READ demo + printfn "Reading data from table, press any key to continue... " + Console.ReadKey(true) |> ignore + let sql = "SELECT Id, Name, Location FROM Employees;" + use command = new SqlCommand(sql, connection) + use reader = command.ExecuteReader() + + while reader.Read() do + printfn "%i %s %s" (reader.GetInt32(0)) (reader.GetString(1)) (reader.GetString(2)) + + with + | ex -> printfn "%O" ex + + printfn "All done. Press the any key to finish..." + Console.ReadKey(true) |> ignore + + 0 // return an integer exit code diff --git a/samples/tutorials/f#/SqlServerSample/SqlServerSample.fsproj b/samples/tutorials/f#/SqlServerSample/SqlServerSample.fsproj new file mode 100644 index 00000000..7c510289 --- /dev/null +++ b/samples/tutorials/f#/SqlServerSample/SqlServerSample.fsproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + + + + From 64dff83b5e0998e99303dcfd97c5be53153c0246 Mon Sep 17 00:00:00 2001 From: Keys Date: Fri, 19 Oct 2018 15:50:38 +0100 Subject: [PATCH 2/3] porting the C# columnstore example to F# --- .../f#/SqlServerColumnstoreSample/Program.fs | 88 +++++++++++++++++++ .../SqlServerColumnstoreSample.fsproj | 16 ++++ 2 files changed, 104 insertions(+) create mode 100644 samples/tutorials/f#/SqlServerColumnstoreSample/Program.fs create mode 100644 samples/tutorials/f#/SqlServerColumnstoreSample/SqlServerColumnstoreSample.fsproj diff --git a/samples/tutorials/f#/SqlServerColumnstoreSample/Program.fs b/samples/tutorials/f#/SqlServerColumnstoreSample/Program.fs new file mode 100644 index 00000000..7a39e5e9 --- /dev/null +++ b/samples/tutorials/f#/SqlServerColumnstoreSample/Program.fs @@ -0,0 +1,88 @@ +// Learn more about F# at http://fsharp.org + +open System +open System.Data.SqlClient + +let SumPrice connection = + let sql = "SELECT SUM(Price) FROM Table_with_5M_rows;" + let startTicks = DateTime.Now.Ticks; + use command = new SqlCommand(sql, connection) + try + command.ExecuteScalar() |> ignore + let elapsed = TimeSpan.FromTicks(DateTime.Now.Ticks) - TimeSpan.FromTicks(startTicks) + elapsed.TotalMilliseconds + with + | ex -> + printfn "%O" ex + 0. + +let executeSqlCommand sql connection = + use command = new SqlCommand(sql, connection) + command.CommandTimeout <- 300 //5 minutes + command.ExecuteNonQuery() |> ignore + +[] +let main argv = + try + printfn "*** SQL Server Columnstore demo ***" + + // Build connection string + let builder = new SqlConnectionStringBuilder() + builder.DataSource <- "localhost" + builder.UserID <- "sa" + builder.Password <- "your_password" + builder.InitialCatalog <- "master" + + // Connect to SQL + printf "Connecting to SQL Server ... " + use connection = new SqlConnection(builder.ConnectionString) + connection.Open() + printfn "Done." + + // Create a sample database + printf "Dropping and creating database 'FSharpSampleDB' ... " + let sql = "DROP DATABASE IF EXISTS [FSharpSampleDB]; CREATE DATABASE [FSharpSampleDB]" + executeSqlCommand sql connection + printfn "Done." + + // Insert 5 million rows into the table 'Table_with_5M_rows' + printf "Inserting 5 million rows into table 'Table_with_5M_rows'. This takes ~1 minute, please wait ... " + let sql = " + USE FSharpSampleDB; + WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a)) + SELECT TOP(5000000) + ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId + ,a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId + ,a.a * 10 AS Price + ,CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName + INTO Table_with_5M_rows + FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;" + + executeSqlCommand sql connection + printfn "Done." + + // Execute SQL query without columnstore index + let elapsedTimeWithoutIndex = SumPrice(connection) + printfn "Query time WITHOUT columnstore index: %fms" elapsedTimeWithoutIndex + + // Add a Columnstore Index + printf "Adding a columnstore to table 'Table_with_5M_rows' ... " + let sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_5M_rows;" + executeSqlCommand sql connection + printfn "Done." + + // Execute the same SQL query again after columnstore index was added + let elapsedTimeWithIndex = SumPrice(connection) + printfn "Query time WITH columnstore index: %fms" elapsedTimeWithIndex + + // Calculate performance gain from adding columnstore index + Math.Round(elapsedTimeWithoutIndex / elapsedTimeWithIndex) + |> printfn "Performance improvement with columnstore index: %f x!" + + printfn "All done. Press any key to finish..." + Console.ReadKey(true) |> ignore + + with + | ex -> printfn "%O" ex + + 0 // return an integer exit code diff --git a/samples/tutorials/f#/SqlServerColumnstoreSample/SqlServerColumnstoreSample.fsproj b/samples/tutorials/f#/SqlServerColumnstoreSample/SqlServerColumnstoreSample.fsproj new file mode 100644 index 00000000..7c510289 --- /dev/null +++ b/samples/tutorials/f#/SqlServerColumnstoreSample/SqlServerColumnstoreSample.fsproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + + + + From 9fab24e57b183e3bc42f13bb421f99752f14ba82 Mon Sep 17 00:00:00 2001 From: Keys Date: Fri, 19 Oct 2018 15:53:07 +0100 Subject: [PATCH 3/3] update READMEs --- samples/README.md | 2 +- samples/tutorials/README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/README.md b/samples/README.md index b0851504..15dc084d 100644 --- a/samples/README.md +++ b/samples/README.md @@ -22,7 +22,7 @@ Samples that help with the management of SQL Server and Azure SQL Database. __[tutorials](tutorials/)__ -Samples showing how to connect to SQL databases using various programming languages, including Python, C#, Java, Ruby, Node.js, and PHP. +Samples showing how to connect to SQL databases using various programming languages, including Python, C#, F#, Java, Ruby, Node.js, and PHP. __[containers](containers/)__ diff --git a/samples/tutorials/README.md b/samples/tutorials/README.md index cb4f78e3..e4d025e4 100644 --- a/samples/tutorials/README.md +++ b/samples/tutorials/README.md @@ -4,6 +4,7 @@ Contains samples that show how to connect to Microsoft SQL databases, including SQL Server, Azure SQL Database, and Azure SQL Data Warehouse from different langauges like: * C# * C/C++ +* F# * Java * Node.js * PHP