From 38d2067b56a6bb89a29f453c976f3781de5fa735 Mon Sep 17 00:00:00 2001 From: akatesmith Date: Tue, 15 Sep 2020 12:04:31 -0700 Subject: [PATCH 1/3] Adding Azure based samples --- samples/tutorials/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/tutorials/README.md b/samples/tutorials/README.md index e4d025e4a9..35e4e6141b 100644 --- a/samples/tutorials/README.md +++ b/samples/tutorials/README.md @@ -12,5 +12,8 @@ Contains samples that show how to connect to Microsoft SQL databases, including * Ruby +You can find many Azure-specific samples in the AzureSqlGettingStarted folder. + + From 50468c14d36cc7d7a2e88bfbf741f288dbf75e94 Mon Sep 17 00:00:00 2001 From: akatesmith Date: Tue, 15 Sep 2020 12:20:56 -0700 Subject: [PATCH 2/3] adding azure sql samples Adding the samples content from extending the getting started website for azure specific workflows --- .../csharp/Readme.md | 7 + .../AzureSqlColumnstoreSample/Program.cs | 136 ++++++++++++ .../AzureSqlEFSample/EFSampleContext.cs | 22 ++ .../Unix-based/AzureSqlEFSample/Program.cs | 113 ++++++++++ .../Unix-based/AzureSqlEFSample/Task.cs | 18 ++ .../Unix-based/AzureSqlEFSample/User.cs | 22 ++ .../Unix-based/AzureSqlSample/Program.cs | 135 ++++++++++++ .../AzureSqlSample/Program_KeyVault.cs | 160 +++++++++++++++ .../csharp/Unix-based/Readme.md | 11 + .../AzureSqlColumnstoreSample/Program.cs | 139 +++++++++++++ .../AzureSqlEFSample/EFSampleContext.cs | 16 ++ .../Windows/AzureSqlEFSample/Program.cs | 110 ++++++++++ .../csharp/Windows/AzureSqlEFSample/Task.cs | 18 ++ .../csharp/Windows/AzureSqlEFSample/User.cs | 23 +++ .../csharp/Windows/AzureSqlSample/Program.cs | 135 ++++++++++++ .../AzureSqlSample/Program_KeyVault.cs | 160 +++++++++++++++ .../csharp/Windows/Readme.md | 11 + .../go/Readme.md | 5 + .../go/columnstore.go | 63 ++++++ .../go/connect.go | 59 ++++++ .../AzureSqlGettingStartedSamples/go/crud.go | 190 +++++++++++++++++ .../AzureSqlGettingStartedSamples/go/orm.go | 103 ++++++++++ .../java/Readme.md | 7 + .../AzureSqlColumnstoreSample/App.java | 117 +++++++++++ .../AzureSqlColumnstoreSample/pom.xml | 50 +++++ .../AzureSqlHibernateSample/App.java | 169 +++++++++++++++ .../AzureSqlHibernateSample/Task.java | 77 +++++++ .../AzureSqlHibernateSample/User.java | 70 +++++++ .../AzureSqlHibernateSample/pom.xml | 66 ++++++ .../java/Unix-based/AzureSqlSample/App.java | 111 ++++++++++ .../AzureSqlSample/App_KeyVault.java | 126 ++++++++++++ .../java/Unix-based/AzureSqlSample/pom.xml | 99 +++++++++ .../java/Unix-based/Readme.md | 11 + .../AzureSqlColumnstoreSample/App.java | 117 +++++++++++ .../Windows/AzureSqlColumnstoreSample/pom.xml | 50 +++++ .../Windows/AzureSqlHibernateSample/App.java | 169 +++++++++++++++ .../Windows/AzureSqlHibernateSample/Task.java | 77 +++++++ .../Windows/AzureSqlHibernateSample/User.java | 69 +++++++ .../Windows/AzureSqlHibernateSample/pom.xml | 66 ++++++ .../java/Windows/AzureSqlSample/App.java | 111 ++++++++++ .../Windows/AzureSqlSample/App_KeyVault.java | 126 ++++++++++++ .../java/Windows/AzureSqlSample/pom.xml | 99 +++++++++ .../java/Windows/Readme.md | 11 + .../nodejs/Readme.md | 7 + .../AzureSqlColumnstoreSample/columnstore.js | 99 +++++++++ .../Unix-based/AzureSqlSample/connect.js | 32 +++ .../nodejs/Unix-based/AzureSqlSample/crud.js | 150 ++++++++++++++ .../AzureSqlSample/crud_KeyVault.js | 193 ++++++++++++++++++ .../Unix-based/AzureSqlSequelizeSample/orm.js | 147 +++++++++++++ .../nodejs/Unix-based/Readme.md | 11 + .../AzureSqlColumnstoreSample/columnstore.js | 101 +++++++++ .../nodejs/Windows/AzureSqlSample/connect.js | 31 +++ .../nodejs/Windows/AzureSqlSample/crud.js | 147 +++++++++++++ .../Windows/AzureSqlSample/crud_KeyVault.js | 192 +++++++++++++++++ .../Windows/AzureSqlSequelizeSample/orm.js | 147 +++++++++++++ .../nodejs/Windows/Readme.md | 11 + .../php/Readme.md | 7 + .../AzureSqlColumnstoreSample/columnstore.php | 41 ++++ .../php/Unix-based/AzureSqlSample/connect.php | 12 ++ .../php/Unix-based/AzureSqlSample/crud.php | 74 +++++++ .../php/Unix-based/Readme.md | 11 + .../AzureSqlColumnstoreSample/columnstore.php | 42 ++++ .../php/Windows/AzureSqlSample/connect.php | 12 ++ .../php/Windows/AzureSqlSample/crud.php | 74 +++++++ .../php/Windows/Readme.md | 11 + .../python/Readme.md | 7 + .../AzureSqlColumnstoreSample/columnstore.py | 29 +++ .../python/Unix-based/AzureSqlSample/crud.py | 37 ++++ .../AzureSqlSample/crud_KeyVault.py | 50 +++++ .../python/Unix-based/Readme.md | 11 + .../AzureSqlColumnstoreSample/columnstore.py | 29 +++ .../python/Windows/AzureSqlSample/crud.py | 37 ++++ .../Windows/AzureSqlSample/crud_KeyVault.py | 50 +++++ .../python/Windows/Readme.md | 11 + .../AzureSqlColumnstoreSample/columnstore.rb | 53 +++++ .../ruby/AzureSqlSample/activerecordcrud.rb | 56 +++++ .../ruby/AzureSqlSample/connect.rb | 9 + .../ruby/AzureSqlSample/crud.rb | 45 ++++ .../ruby/Readme.md | 4 + 79 files changed, 5434 insertions(+) create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlColumnstoreSample/Program.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/EFSampleContext.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Program.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Task.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/User.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program_KeyVault.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlColumnstoreSample/Program.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/EFSampleContext.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Program.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Task.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/User.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program_KeyVault.cs create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/go/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/go/columnstore.go create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/go/connect.go create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/go/crud.go create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/go/orm.go create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/App.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/pom.xml create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/App.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/Task.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/User.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/pom.xml create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App_KeyVault.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/pom.xml create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/App.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/pom.xml create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/App.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/Task.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/User.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/pom.xml create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App_KeyVault.java create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/pom.xml create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlColumnstoreSample/columnstore.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/connect.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud_KeyVault.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSequelizeSample/orm.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlColumnstoreSample/columnstore.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/connect.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud_KeyVault.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSequelizeSample/orm.js create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlColumnstoreSample/columnstore.php create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/connect.php create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/crud.php create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlColumnstoreSample/columnstore.php create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/connect.php create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/crud.php create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlColumnstoreSample/columnstore.py create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud.py create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud_KeyVault.py create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlColumnstoreSample/columnstore.py create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud.py create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud_KeyVault.py create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/Readme.md create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlColumnstoreSample/columnstore.rb create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/activerecordcrud.rb create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/connect.rb create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/crud.rb create mode 100644 samples/tutorials/AzureSqlGettingStartedSamples/ruby/Readme.md diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md new file mode 100644 index 0000000000..2508e863a8 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md @@ -0,0 +1,7 @@ +# Developing applications with C# and Azure SQL + +Pick a platform below to get started: +* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](linktodo) +* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/java/Windows) + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlColumnstoreSample/Program.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlColumnstoreSample/Program.cs new file mode 100644 index 0000000000..fc44147cd0 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlColumnstoreSample/Program.cs @@ -0,0 +1,136 @@ +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.KeyVault.Models; +using Microsoft.Azure.Services.AppAuthentication; +using System; +using System.Data.SqlClient; +using System.Text; +using System.Threading.Tasks; + +namespace AzureSqlColumnstoreSample +{ + class Program + { + static void Main(string[] args) + { + System.Threading.Tasks.Task task = Program.DoWork(args); + // Becuase this program takes user input, have a long wait. + var result = task.Wait(TimeSpan.FromMinutes(30)); + } + + static async System.Threading.Tasks.Task DoWork(string[] args) + { + + Console.WriteLine("*** Azure SQL Columnstore demo ***"); + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server.database.windows.net"; // update me + builder.UserID = "your_user"; // update me + builder.Password = await GetPasswordFromKeyVault(); + builder.InitialCatalog = "your_database"; + + // Connect to Azure SQL + Console.Write("Connecting to Azure SQL ... "); + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + { + string sql; + try + { + connection.Open(); + string dropTable = "Drop table if exists Table_with_3M_rows"; + using (SqlCommand command = new SqlCommand(dropTable, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Table cleaned up."); + } + + // Insert 5 million rows into the table 'Table_with_3M_rows' + Console.Write("Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... "); + StringBuilder sb = new StringBuilder(); + sb.Append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))"); + sb.Append("SELECT TOP(3000000)"); + sb.Append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId "); + sb.Append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId "); + sb.Append(",a.a * 10 AS Price "); + sb.Append(",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 "); + sb.Append("INTO Table_with_3M_rows "); + sb.Append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // Execute SQL query without columnstore index + double elapsedTimeWithoutIndex = SumPrice(connection); + Console.WriteLine("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms"); + + // Add a Columnstore Index + Console.Write("Adding a columnstore to table 'Table_with_3M_rows' ... "); + sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;"; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // Execute the same SQL query again after columnstore index was added + double elapsedTimeWithIndex = SumPrice(connection); + Console.WriteLine("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms"); + + // Calculate performance gain from adding columnstore index + Console.WriteLine("Performance improvement with columnstore index: " + + Math.Round(elapsedTimeWithoutIndex / elapsedTimeWithIndex) + "x!"); + } + + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + finally + { + string dropTable = "Drop table if exists Table_with_3M_rows"; + using (SqlCommand command = new SqlCommand(dropTable, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Table cleaned up."); + } + } + } + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + + private static async Task GetPasswordFromKeyVault() + { + Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue..."); + Console.ReadKey(true); + /* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */ + AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); + KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); + SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me + return secret.Value; + } + + public static double SumPrice(SqlConnection connection) + { + String sql = "SELECT SUM(Price) FROM Table_with_3M_rows"; + long startTicks = DateTime.Now.Ticks; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + try + { + var sum = command.ExecuteScalar(); + TimeSpan elapsed = TimeSpan.FromTicks(DateTime.Now.Ticks) - TimeSpan.FromTicks(startTicks); + return elapsed.TotalMilliseconds; + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + return 0; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/EFSampleContext.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/EFSampleContext.cs new file mode 100644 index 0000000000..750feaf739 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/EFSampleContext.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.SqlServer; + +namespace AzureSqlEFSample +{ + public class EFSampleContext : DbContext + { + string _connectionString; + public EFSampleContext(string connectionString) + { + this._connectionString = connectionString; + + } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(this._connectionString); + } + + public DbSet Users { get; set; } + public DbSet Tasks { get; set; } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Program.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Program.cs new file mode 100644 index 0000000000..e2da50da3e --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Program.cs @@ -0,0 +1,113 @@ +using System; +using System.Data.SqlClient; +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.KeyVault.Models; +using Microsoft.Azure.Services.AppAuthentication; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; + +namespace AzureSqlEFSample +{ + class Program + { + static void Main(string[] args) + { + System.Threading.Tasks.Task task = Program.DoWork(args); + // Becuase this program takes user input, have a long wait. + var result = task.Wait(TimeSpan.FromMinutes(30)); + } + + static async System.Threading.Tasks.Task DoWork(string[] args) + { + Console.WriteLine("** C# CRUD sample with Entity Framework and Azure SQL DB**\n"); + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server_name.database.windows.net"; // update me + builder.UserID = "your_user"; // update me + builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault + builder.InitialCatalog = "your_db_name"; // Update me + + using (EFSampleContext context = new EFSampleContext(builder.ConnectionString)) + { + try + { + context.Database.EnsureDeleted(); + context.Database.EnsureCreated(); + Console.WriteLine("Created database schema from C# classes."); + + // Create demo: Create a Task instance and save it to the database + Task newTask = new Task() { Title = "Ship Helsinki", IsComplete = false, DueDate = DateTime.Parse("04-01-2017") }; + context.Tasks.Add(newTask); + context.SaveChanges(); + Console.WriteLine("\nCreated Task: " + newTask.ToString()); + + // Association demo: Assign task to user + + // Read demo: find incomplete tasks assigned to user 'Anna' + Console.WriteLine("\nIncomplete tasks assigned to 'Anna':"); + var query = from t in context.Tasks + where t.IsComplete == false && + t.AssignedTo.FirstName.Equals("Anna") + select t; + foreach (var t in query) + { + Console.WriteLine(t.ToString()); + } + + // Update demo: change the 'dueDate' of a task + Task taskToUpdate = context.Tasks.First(); // get the first task + Console.WriteLine("\nUpdating task: " + taskToUpdate.ToString()); + taskToUpdate.DueDate = DateTime.Parse("06-30-2016"); + context.SaveChanges(); + Console.WriteLine("dueDate changed: " + taskToUpdate.ToString()); + + // Delete demo: delete all tasks with a dueDate in 2016 + Console.WriteLine("\nDeleting all tasks with a dueDate in 2016"); + DateTime dueDate2016 = DateTime.Parse("12-31-2016"); + List queryResults = context.Tasks.Where(t => t.DueDate < dueDate2016).ToList(); + foreach (Task t in queryResults) + { + Console.WriteLine("Deleting task: " + t.ToString()); + context.Tasks.Remove(t); + } + context.SaveChanges(); + + // Show tasks after the 'Delete' operation - there should be 0 tasks + Console.WriteLine("\nTasks after delete:"); + List tasksAfterDelete = (from t in context.Tasks select t).ToList(); + if (tasksAfterDelete.Count == 0) + { + Console.WriteLine("[None]"); + } + else + { + foreach (Task t in query) + { + Console.WriteLine(t.ToString()); + } + } + } + catch (SqlException e) + { + Console.WriteLine(e.ToString()); + } + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + + private static async Task GetPasswordFromKeyVault() + { + Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue..."); + Console.ReadKey(true); + /* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */ + AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); + KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); + SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me + return secret.Value; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Task.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Task.cs new file mode 100644 index 0000000000..c9067532de --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/Task.cs @@ -0,0 +1,18 @@ +using System; + +namespace AzureSqlEFSample +{ + public class Task + { + public int TaskId { get; set; } + public string Title { get; set; } + public DateTime DueDate { get; set; } + public bool IsComplete { get; set; } + public virtual User AssignedTo { get; set; } + + public override string ToString() + { + return "Task [id=" + this.TaskId + ", title=" + this.Title + ", dueDate=" + this.DueDate.ToString() + ", IsComplete=" + this.IsComplete + "]"; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/User.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/User.cs new file mode 100644 index 0000000000..5dfd2930e6 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlEFSample/User.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace AzureSqlEFSample +{ + public class User + { + public int UserId { get; set; } + public String FirstName { get; set; } + public String LastName { get; set; } + public virtual IList Tasks { get; set; } + + public String GetFullName() + { + return this.FirstName + " " + this.LastName; + } + public override string ToString() + { + return "User [id=" + this.UserId + ", name=" + this.GetFullName() + "]"; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program.cs new file mode 100644 index 0000000000..2da9966d12 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program.cs @@ -0,0 +1,135 @@ +using System; +using System.Text; +using System.Data.SqlClient; + +namespace AzureSqlSample +{ + class Program + { + static void Main(string[] args) + { + string sql; + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server_name.database.windows.net"; // update me + builder.UserID = "your_user"; // update me + builder.Password = "your_password"; // update me + builder.InitialCatalog = "your_database_name"; // update me + + // Connect to Azure SQL + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + { + try + { + Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Connect to Azure SQL + Console.Write("Connecting to Azure SQL ... "); + connection.Open(); + Console.WriteLine("Done."); + + using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection)) + { + command.ExecuteNonQuery(); + } + + + // Create a Table and insert some sample data + Console.Write("Creating sample table with data, press any key to continue..."); + Console.ReadKey(true); + StringBuilder sb = new StringBuilder(); + sb.Append("CREATE TABLE Employees ( "); + sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, "); + sb.Append(" Name NVARCHAR(50), "); + sb.Append(" Location NVARCHAR(50) "); + sb.Append("); "); + sb.Append("INSERT INTO Employees (Name, Location) VALUES "); + sb.Append("(N'Jared', N'Australia'), "); + sb.Append("(N'Nikita', N'India'), "); + sb.Append("(N'Tom', N'Germany'); "); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // INSERT demo + Console.Write("Inserting a new row into table, press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("INSERT Employees (Name, Location) "); + sb.Append("VALUES (@name, @location);"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", "Jake"); + command.Parameters.AddWithValue("@location", "United States"); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToUpdate); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + Console.Write("Deleting user '" + userToDelete + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("DELETE FROM Employees WHERE Name = @name;"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToDelete); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) deleted"); + } + + // READ demo + Console.WriteLine("Reading data from table, press any key to continue..."); + Console.ReadKey(true); + sql = "SELECT Id, Name, Location FROM Employees;"; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2)); + } + } + } + } + catch (SqlException e) + { + Console.WriteLine(e.ToString()); + } + finally + { + Console.WriteLine("Cleaning up table."); + using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection)) + { + command.ExecuteNonQuery(); + } + } + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program_KeyVault.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program_KeyVault.cs new file mode 100644 index 0000000000..f8d4028285 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/AzureSqlSample/Program_KeyVault.cs @@ -0,0 +1,160 @@ +using System; +using System.Text; +using System.Data.SqlClient; +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.KeyVault.Models; +using Microsoft.Azure.Services.AppAuthentication; +using System.Threading.Tasks; + +namespace AzureSQLSample +{ + class Program + { + static void Main(string[] args) + { + Task task = Program.DoWork(args); + // Becuase this program takes user input, have a long wait. + var result = task.Wait(TimeSpan.FromMinutes(30)); + } + + static async Task DoWork(string[] args) + { + string sql; + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server_name.database.windows.net"; // update me + builder.UserID = "your_user_id"; // update me + builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault + builder.InitialCatalog = "your_database"; // Update me + + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + { + try + { + Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Connect to Azure SQL + Console.Write("Connecting to Azure SQL ... "); + connection.Open(); + Console.WriteLine("Done."); + + string dropTableIfExists = @"DROP TABLE IF EXISTS Employees"; + using (SqlCommand command = new SqlCommand(dropTableIfExists, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + + // Create a Table and insert some sample data + Console.Write("Creating sample table with data, press any key to continue..."); + Console.ReadKey(true); + StringBuilder sb = new StringBuilder(); + sb.Append("CREATE TABLE Employees ( "); + sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, "); + sb.Append(" Name NVARCHAR(50), "); + sb.Append(" Location NVARCHAR(50) "); + sb.Append("); "); + sb.Append("INSERT INTO Employees (Name, Location) VALUES "); + sb.Append("(N'Jared', N'Australia'), "); + sb.Append("(N'Nikita', N'India'), "); + sb.Append("(N'Tom', N'Germany'); "); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // INSERT demo + Console.Write("Inserting a new row into table, press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("INSERT Employees (Name, Location) "); + sb.Append("VALUES (@name, @location);"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", "Jake"); + command.Parameters.AddWithValue("@location", "United States"); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToUpdate); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + Console.Write("Deleting user '" + userToDelete + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("DELETE FROM Employees WHERE Name = @name;"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToDelete); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) deleted"); + } + + // READ demo + Console.WriteLine("Reading data from table, press any key to continue..."); + Console.ReadKey(true); + sql = "SELECT Id, Name, Location FROM Employees;"; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2)); + } + } + } + } + catch (SqlException e) + { + Console.WriteLine(e.ToString()); + } + finally + { + Console.WriteLine("Cleaning up table."); + string dropTableIfExists = @"DROP TABLE IF EXISTS Employees"; + using (SqlCommand command = new SqlCommand(dropTableIfExists, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + } + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + + private static async Task GetPasswordFromKeyVault() + { + Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue..."); + Console.ReadKey(true); + /* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */ + AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); + KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); + SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_key_vault_name.vault.azure.net/secrets/AppSecret"); // update me + return secret.Value; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/Readme.md new file mode 100644 index 0000000000..1a374b9b69 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [C# tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlColumnstoreSample/Program.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlColumnstoreSample/Program.cs new file mode 100644 index 0000000000..0a6a499720 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlColumnstoreSample/Program.cs @@ -0,0 +1,139 @@ +using System; +using System.Text; +using System.Data.SqlClient; +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.KeyVault.Models; +using Microsoft.Azure.Services.AppAuthentication; +using System.Threading.Tasks; + +namespace AzureSQLSample +{ + class Program + { + static void Main(string[] args) + { + Task task = Program.DoWork(args); + + // Because this program waits for user input, use a long wait. + var result = task.Wait(TimeSpan.FromMinutes(30)); + } + + static async Task DoWork(string[] args) + { + string sql; + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server.database.windows.net"; // update me + builder.UserID = "your_user"; // update me + builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault + builder.InitialCatalog = "your_db"; // Update me + + // Connect to SQL + Console.Write("Connecting to Azure SQL ... "); + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + { + try + { + // Connect to SQL + Console.Write("Connecting to Azure SQL ... "); + connection.Open(); + Console.WriteLine("Done."); + + string dropTableIfExists = @"DROP TABLE IF EXISTS Table_with_3M_rows"; + using (SqlCommand command = new SqlCommand(dropTableIfExists, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // Insert 3 million rows into the table 'Table_with_3M_rows' + Console.Write("Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... "); + StringBuilder sb = new StringBuilder(); + sb.Append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))"); + sb.Append("SELECT TOP(3000000)"); + sb.Append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId "); + sb.Append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId "); + sb.Append(",a.a * 10 AS Price "); + sb.Append(",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 "); + sb.Append("INTO Table_with_3M_rows "); + sb.Append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // Execute SQL query without columnstore index + double elapsedTimeWithoutIndex = SumPrice(connection); + Console.WriteLine("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms"); + + // Add a Columnstore Index + Console.Write("Adding a columnstore to table 'Table_with_3M_rows' ... "); + sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;"; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // Execute the same SQL query again after columnstore index was added + double elapsedTimeWithIndex = SumPrice(connection); + Console.WriteLine("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms"); + + // Calculate performance gain from adding columnstore index + Console.WriteLine("Performance improvement with columnstore index: " + + Math.Round(elapsedTimeWithoutIndex / elapsedTimeWithIndex) + "x!"); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + finally + { + string dropTableIfExists = @"DROP TABLE IF EXISTS Table_with_3M_rows"; + using (SqlCommand command = new SqlCommand(dropTableIfExists, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + } + } + + public static double SumPrice(SqlConnection connection) + { + String sql = "SELECT SUM(Price) FROM Table_with_3M_rows"; + long startTicks = DateTime.Now.Ticks; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + try + { + var sum = command.ExecuteScalar(); + TimeSpan elapsed = TimeSpan.FromTicks(DateTime.Now.Ticks) - TimeSpan.FromTicks(startTicks); + return elapsed.TotalMilliseconds; + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + return 0; + } + + private static async Task GetPasswordFromKeyVault() + { + Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue..."); + Console.ReadKey(true); + /* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */ + AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); + KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); + SecretBundle secret = await keyVaultClient.GetSecretAsync("https://you_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me + return secret.Value; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/EFSampleContext.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/EFSampleContext.cs new file mode 100644 index 0000000000..1472efbb13 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/EFSampleContext.cs @@ -0,0 +1,16 @@ +using System; +using System.Data.Entity; + +namespace AzureSqlEFSample +{ + public class EFSampleContext : DbContext + { + public EFSampleContext(string connectionString) + { + Database.SetInitializer(new CreateDatabaseIfNotExists()); + this.Database.Connection.ConnectionString = connectionString; + } + public DbSet Users { get; set; } + public DbSet Tasks { get; set; } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Program.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Program.cs new file mode 100644 index 0000000000..100021aabf --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Program.cs @@ -0,0 +1,110 @@ +using System; +using System.Data.SqlClient; +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.KeyVault.Models; +using Microsoft.Azure.Services.AppAuthentication; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; + +namespace AzureSqlEFSample +{ + class Program + { + static void Main(string[] args) + { + System.Threading.Tasks.Task task = Program.DoWork(args); + // Becuase this program takes user input, have a long wait. + var result = task.Wait(TimeSpan.FromMinutes(30)); + } + + static async System.Threading.Tasks.Task DoWork(string[] args) + { + string sql; + Console.WriteLine("** C# CRUD sample with Entity Framework and Azure SQL **\n"); + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server.database.windows.net"; // update me + builder.UserID = "your_user"; // update me + builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault + builder.InitialCatalog = "your_db"; // Update me + + using (EFSampleContext context = new EFSampleContext(builder.ConnectionString)) + { + try + { + // Create demo: Create a Task instance and save it to the database + Task newTask = new Task() { Title = "Ship Helsinki", IsComplete = false, DueDate = DateTime.Parse("04-01-2017") }; + context.Tasks.Add(newTask); + context.SaveChanges(); + Console.WriteLine("\nCreated Task: " + newTask.ToString()); + + // Association demo: Assign task to user + + // Read demo: find incomplete tasks assigned to user 'Anna' + Console.WriteLine("\nIncomplete tasks assigned to 'Anna':"); + var query = from t in context.Tasks + where t.IsComplete == false && + t.AssignedTo.FirstName.Equals("Anna") + select t; + foreach (var t in query) + { + Console.WriteLine(t.ToString()); + } + + // Update demo: change the 'dueDate' of a task + Task taskToUpdate = context.Tasks.First(); // get the first task + Console.WriteLine("\nUpdating task: " + taskToUpdate.ToString()); + taskToUpdate.DueDate = DateTime.Parse("06-30-2016"); + context.SaveChanges(); + Console.WriteLine("dueDate changed: " + taskToUpdate.ToString()); + + // Delete demo: delete all tasks with a dueDate in 2016 + Console.WriteLine("\nDeleting all tasks with a dueDate in 2016"); + DateTime dueDate2016 = DateTime.Parse("12-31-2016"); + List queryResults = context.Tasks.Where(t => t.DueDate < dueDate2016).ToList(); + foreach (Task t in queryResults) + { + Console.WriteLine("Deleting task: " + t.ToString()); + context.Tasks.Remove(t); + } + context.SaveChanges(); + + // Show tasks after the 'Delete' operation - there should be 0 tasks + Console.WriteLine("\nTasks after delete:"); + List tasksAfterDelete = (from t in context.Tasks select t).ToList(); + if (tasksAfterDelete.Count == 0) + { + Console.WriteLine("[None]"); + } + else + { + foreach (Task t in query) + { + Console.WriteLine(t.ToString()); + } + } + } + catch (SqlException e) + { + Console.WriteLine(e.ToString()); + } + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + + private static async Task GetPasswordFromKeyVault() + { + Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue..."); + Console.ReadKey(true); + /* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */ + AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); + KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); + SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_keyvault_name.vault.azure.net/secrets/AppSecret"); // update me + return secret.Value; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Task.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Task.cs new file mode 100644 index 0000000000..c9067532de --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/Task.cs @@ -0,0 +1,18 @@ +using System; + +namespace AzureSqlEFSample +{ + public class Task + { + public int TaskId { get; set; } + public string Title { get; set; } + public DateTime DueDate { get; set; } + public bool IsComplete { get; set; } + public virtual User AssignedTo { get; set; } + + public override string ToString() + { + return "Task [id=" + this.TaskId + ", title=" + this.Title + ", dueDate=" + this.DueDate.ToString() + ", IsComplete=" + this.IsComplete + "]"; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/User.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/User.cs new file mode 100644 index 0000000000..7849ee9c96 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlEFSample/User.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace AzureSqlEFSample +{ + public class User + { + public int UserId { get; set; } + public String FirstName { get; set; } + public String LastName { get; set; } + public virtual IList Tasks { get; set; } + + public String GetFullName() + { + return this.FirstName + " " + this.LastName; + } + public override string ToString() + { + return "User [id=" + this.UserId + ", name=" + this.GetFullName() + "]"; + } + } +} +``` \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program.cs new file mode 100644 index 0000000000..2da9966d12 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program.cs @@ -0,0 +1,135 @@ +using System; +using System.Text; +using System.Data.SqlClient; + +namespace AzureSqlSample +{ + class Program + { + static void Main(string[] args) + { + string sql; + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server_name.database.windows.net"; // update me + builder.UserID = "your_user"; // update me + builder.Password = "your_password"; // update me + builder.InitialCatalog = "your_database_name"; // update me + + // Connect to Azure SQL + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + { + try + { + Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Connect to Azure SQL + Console.Write("Connecting to Azure SQL ... "); + connection.Open(); + Console.WriteLine("Done."); + + using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection)) + { + command.ExecuteNonQuery(); + } + + + // Create a Table and insert some sample data + Console.Write("Creating sample table with data, press any key to continue..."); + Console.ReadKey(true); + StringBuilder sb = new StringBuilder(); + sb.Append("CREATE TABLE Employees ( "); + sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, "); + sb.Append(" Name NVARCHAR(50), "); + sb.Append(" Location NVARCHAR(50) "); + sb.Append("); "); + sb.Append("INSERT INTO Employees (Name, Location) VALUES "); + sb.Append("(N'Jared', N'Australia'), "); + sb.Append("(N'Nikita', N'India'), "); + sb.Append("(N'Tom', N'Germany'); "); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // INSERT demo + Console.Write("Inserting a new row into table, press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("INSERT Employees (Name, Location) "); + sb.Append("VALUES (@name, @location);"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", "Jake"); + command.Parameters.AddWithValue("@location", "United States"); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToUpdate); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + Console.Write("Deleting user '" + userToDelete + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("DELETE FROM Employees WHERE Name = @name;"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToDelete); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) deleted"); + } + + // READ demo + Console.WriteLine("Reading data from table, press any key to continue..."); + Console.ReadKey(true); + sql = "SELECT Id, Name, Location FROM Employees;"; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2)); + } + } + } + } + catch (SqlException e) + { + Console.WriteLine(e.ToString()); + } + finally + { + Console.WriteLine("Cleaning up table."); + using (SqlCommand command = new SqlCommand("DROP TABLE IF EXISTS Employees", connection)) + { + command.ExecuteNonQuery(); + } + } + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program_KeyVault.cs b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program_KeyVault.cs new file mode 100644 index 0000000000..f8d4028285 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/AzureSqlSample/Program_KeyVault.cs @@ -0,0 +1,160 @@ +using System; +using System.Text; +using System.Data.SqlClient; +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.KeyVault.Models; +using Microsoft.Azure.Services.AppAuthentication; +using System.Threading.Tasks; + +namespace AzureSQLSample +{ + class Program + { + static void Main(string[] args) + { + Task task = Program.DoWork(args); + // Becuase this program takes user input, have a long wait. + var result = task.Wait(TimeSpan.FromMinutes(30)); + } + + static async Task DoWork(string[] args) + { + string sql; + + // Build connection string + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); + builder.DataSource = "your_server_name.database.windows.net"; // update me + builder.UserID = "your_user_id"; // update me + builder.Password = await GetPasswordFromKeyVault(); // taken from Key Vault + builder.InitialCatalog = "your_database"; // Update me + + using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) + { + try + { + Console.WriteLine("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Connect to Azure SQL + Console.Write("Connecting to Azure SQL ... "); + connection.Open(); + Console.WriteLine("Done."); + + string dropTableIfExists = @"DROP TABLE IF EXISTS Employees"; + using (SqlCommand command = new SqlCommand(dropTableIfExists, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + + // Create a Table and insert some sample data + Console.Write("Creating sample table with data, press any key to continue..."); + Console.ReadKey(true); + StringBuilder sb = new StringBuilder(); + sb.Append("CREATE TABLE Employees ( "); + sb.Append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, "); + sb.Append(" Name NVARCHAR(50), "); + sb.Append(" Location NVARCHAR(50) "); + sb.Append("); "); + sb.Append("INSERT INTO Employees (Name, Location) VALUES "); + sb.Append("(N'Jared', N'Australia'), "); + sb.Append("(N'Nikita', N'India'), "); + sb.Append("(N'Tom', N'Germany'); "); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + + // INSERT demo + Console.Write("Inserting a new row into table, press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("INSERT Employees (Name, Location) "); + sb.Append("VALUES (@name, @location);"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", "Jake"); + command.Parameters.AddWithValue("@location", "United States"); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + Console.Write("Updating 'Location' for user '" + userToUpdate + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("UPDATE Employees SET Location = N'United States' WHERE Name = @name"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToUpdate); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + Console.Write("Deleting user '" + userToDelete + "', press any key to continue..."); + Console.ReadKey(true); + sb.Clear(); + sb.Append("DELETE FROM Employees WHERE Name = @name;"); + sql = sb.ToString(); + using (SqlCommand command = new SqlCommand(sql, connection)) + { + command.Parameters.AddWithValue("@name", userToDelete); + int rowsAffected = command.ExecuteNonQuery(); + Console.WriteLine(rowsAffected + " row(s) deleted"); + } + + // READ demo + Console.WriteLine("Reading data from table, press any key to continue..."); + Console.ReadKey(true); + sql = "SELECT Id, Name, Location FROM Employees;"; + using (SqlCommand command = new SqlCommand(sql, connection)) + { + + using (SqlDataReader reader = command.ExecuteReader()) + { + while (reader.Read()) + { + Console.WriteLine("{0} {1} {2}", reader.GetInt32(0), reader.GetString(1), reader.GetString(2)); + } + } + } + } + catch (SqlException e) + { + Console.WriteLine(e.ToString()); + } + finally + { + Console.WriteLine("Cleaning up table."); + string dropTableIfExists = @"DROP TABLE IF EXISTS Employees"; + using (SqlCommand command = new SqlCommand(dropTableIfExists, connection)) + { + command.ExecuteNonQuery(); + Console.WriteLine("Done."); + } + } + } + + Console.WriteLine("All done. Press any key to finish..."); + Console.ReadKey(true); + } + + private static async Task GetPasswordFromKeyVault() + { + Console.WriteLine("Trying to get Password from Key Vault. Press a key to continue..."); + Console.ReadKey(true); + /* The next four lines of code show you how to use AppAuthentication library to fetch secrets from your key vault */ + AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); + KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); + SecretBundle secret = await keyVaultClient.GetSecretAsync("https://your_key_vault_name.vault.azure.net/secrets/AppSecret"); // update me + return secret.Value; + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/Readme.md new file mode 100644 index 0000000000..dc1611f03f --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [C# on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/csharp/windows/az) to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/go/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/go/Readme.md new file mode 100644 index 0000000000..086331c8c7 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/go/Readme.md @@ -0,0 +1,5 @@ +# Developing applications with Go and Azure SQL + +This information is meant to pair with the steps from [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/), so please follow along there. + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/go/columnstore.go b/samples/tutorials/AzureSqlGettingStartedSamples/go/columnstore.go new file mode 100644 index 0000000000..74ea849ab5 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/go/columnstore.go @@ -0,0 +1,63 @@ +package main + +import ( + _ "github.com/denisenkom/go-mssqldb" + "database/sql" + "context" + "log" + "fmt" + "time" +) + +var server = "your_server.database.windows.net" +var user = "your_user" +var password = "your_password" +var database = "your_database" + +var db *sql.DB + +// Delete an employee from database +func ExecuteAggregateStatement(db *sql.DB) { + ctx := context.Background() + + // Ping database to see if it's still alive. + // Important for handling network issues and long queries. + err := db.PingContext(ctx) + if err != nil { + log.Fatal("Error pinging database: " + err.Error()) + } + + var result string + + // Execute long non-query to aggregate rows + err = db.QueryRowContext(ctx, "SELECT SUM(Price) as sum FROM Table_with_3M_rows").Scan(&result) + if err != nil { + log.Fatal("Error executing query: " + err.Error()) + } + + fmt.Printf("Sum: %s\n", result) +} + +func main() { + // Connect to database + connString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;", + server, user, password, database) + var err error + + // Create connection pool + db, err = sql.Open("sqlserver", connString) + if err != nil { + log.Fatal("Open connection failed:", err.Error()) + } + fmt.Printf("Connected!\n") + + defer db.Close() + + t1 := time.Now() + fmt.Printf("Start time: %s\n", t1) + + ExecuteAggregateStatement(db) + + t2 := time.Since(t1) + fmt.Printf("The query took: %s\n", t2) +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/go/connect.go b/samples/tutorials/AzureSqlGettingStartedSamples/go/connect.go new file mode 100644 index 0000000000..309c64e378 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/go/connect.go @@ -0,0 +1,59 @@ +package main + +import ( + _ "github.com/denisenkom/go-mssqldb" + "database/sql" + "context" + "log" + "fmt" +) + +// Replace with your own connection parameters +var server = "your_server.database.windows.net" +var user = "your_user" +var password = "your_password" +var database = "your_database" + +var db *sql.DB + +func main() { + var err error + + // Create connection string + connString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s", + server, user, password, database) + + // Create connection pool + db, err = sql.Open("sqlserver", connString) + if err != nil { + log.Fatal("Error creating connection pool: " + err.Error()) + } + log.Printf("Connected!\n") + + // Close the database connection pool after program executes + defer db.Close() + + SelectVersion() +} + +// Gets and prints SQL Server version +func SelectVersion(){ + // Use background context + ctx := context.Background() + + // Ping database to see if it's still alive. + // Important for handling network issues and long queries. + err := db.PingContext(ctx) + if err != nil { + log.Fatal("Error pinging database: " + err.Error()) + } + + var result string + + // Run query and scan for result + err = db.QueryRowContext(ctx, "SELECT @@version").coScan(&result) + if err != nil { + log.Fatal("Scan failed:", err.Error()) + } + fmt.Printf("%s\n", result) +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/go/crud.go b/samples/tutorials/AzureSqlGettingStartedSamples/go/crud.go new file mode 100644 index 0000000000..549878b35f --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/go/crud.go @@ -0,0 +1,190 @@ +package main + +import ( + _ "github.com/denisenkom/go-mssqldb" + "database/sql" + "context" + "log" + "fmt" + "errors" +) + +var db *sql.DB + +// Replace with your own connection parameters +var server = "your_server.database.windows.net" +var user = "your_user" +var password = "your_password" +var database = "your_database" + + +func main() { + // Build connection string + connString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;", + server, user, password, database) + + var err error + + // Create connection pool + db, err = sql.Open("sqlserver", connString) + if err != nil { + log.Fatal("Error creating connection pool: ", err.Error()) + } + ctx := context.Background() + err = db.PingContext(ctx) + if err != nil { + log.Fatal(err.Error()) + } + fmt.Printf("Connected!\n") + + // Create employee + createID, err := CreateEmployee("Jake", "United States") + if err != nil { + log.Fatal("Error creating Employee: ", err.Error()) + } + fmt.Printf("Inserted ID: %d successfully.\n", createID) + + // Read employees + count, err := ReadEmployees() + if err != nil { + log.Fatal("Error reading Employees: ", err.Error()) + } + fmt.Printf("Read %d row(s) successfully.\n", count) + + // Update from database + updatedRows, err := UpdateEmployee("Jake", "Poland") + if err != nil { + log.Fatal("Error updating Employee: ", err.Error()) + } + fmt.Printf("Updated %d row(s) successfully.\n", updatedRows) + + // Delete from database + deletedRows, err := DeleteEmployee("Jake") + if err != nil { + log.Fatal("Error deleting Employee: ", err.Error()) + } + fmt.Printf("Deleted %d row(s) successfully.\n", deletedRows) +} + +// CreateEmployee inserts an employee record +func CreateEmployee(name string, location string) (int64, error) { + ctx := context.Background() + var err error + + if db == nil { + err = errors.New("CreateEmployee: db is null") + return -1, err + } + + // Check if database is alive. + err = db.PingContext(ctx) + if err != nil { + return -1, err + } + + tsql := "INSERT INTO TestSchema.Employees (Name, Location) VALUES (@Name, @Location); select convert(bigint, SCOPE_IDENTITY());" + + stmt, err := db.Prepare(tsql) + if err != nil { + return -1, err + } + defer stmt.Close() + + row := stmt.QueryRowContext( + ctx, + sql.Named("Name", name), + sql.Named("Location", location)) + var newID int64 + err = row.Scan(&newID) + if err != nil { + return -1, err + } + + return newID, nil +} + +// ReadEmployees reads all employee records +func ReadEmployees() (int, error) { + ctx := context.Background() + + // Check if database is alive. + err := db.PingContext(ctx) + if err != nil { + return -1, err + } + + tsql := fmt.Sprintf("SELECT Id, Name, Location FROM TestSchema.Employees;") + + // Execute query + rows, err := db.QueryContext(ctx, tsql) + if err != nil { + return -1, err + } + + defer rows.Close() + + var count int + + // Iterate through the result set. + for rows.Next() { + var name, location string + var id int + + // Get values from row. + err := rows.Scan(&id, &name, &location) + if err != nil { + return -1, err + } + + fmt.Printf("ID: %d, Name: %s, Location: %s\n", id, name, location) + count++ + } + + return count, nil +} + +// UpdateEmployee updates an employee's information +func UpdateEmployee(name string, location string) (int64, error) { + ctx := context.Background() + + // Check if database is alive. + err := db.PingContext(ctx) + if err != nil { + return -1, err + } + + tsql := fmt.Sprintf("UPDATE TestSchema.Employees SET Location = @Location WHERE Name = @Name") + + // Execute non-query with named parameters + result, err := db.ExecContext( + ctx, + tsql, + sql.Named("Location", location), + sql.Named("Name", name)) + if err != nil { + return -1, err + } + + return result.RowsAffected() +} + +// DeleteEmployee deletes an employee from the database +func DeleteEmployee(name string) (int64, error) { + ctx := context.Background() + + // Check if database is alive. + err := db.PingContext(ctx) + if err != nil { + return -1, err + } + + tsql := fmt.Sprintf("DELETE FROM TestSchema.Employees WHERE Name = @Name;") + + // Execute non-query with named parameters + result, err := db.ExecContext(ctx, tsql, sql.Named("Name", name)) + if err != nil { + return -1, err + } + + return result.RowsAffected() +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/go/orm.go b/samples/tutorials/AzureSqlGettingStartedSamples/go/orm.go new file mode 100644 index 0000000000..0e397c9a56 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/go/orm.go @@ -0,0 +1,103 @@ + package main + + import ( + "fmt" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mssql" + "log" + ) + + var server = "your_server.database.windows.net" + var user = "your_user" + var password = "your_password" + var database = "your_database" + + // Define a User model struct + type User struct { + gorm.Model + FirstName string + LastName string + } + + // Define a Task model struct + type Task struct { + gorm.Model + Title string + DueDate string + IsComplete bool + UserID uint + } + + // Read and print all the tasks + func ReadAllTasks(db *gorm.DB){ + var users []User + var tasks []Task + db.Find(&users) + + for _, user := range users{ + db.Model(&user).Related(&tasks) + fmt.Printf("%s %s's tasks:\n", user.FirstName, user.LastName) + for _, task := range tasks { + fmt.Printf("Title: %s\nDueDate: %s\nIsComplete:%t\n\n", + task.Title, task.DueDate, task.IsComplete) + } + } + } + + // Update a task based on a user + func UpdateSomeonesTask(db *gorm.DB, userId int){ + var task Task + db.Where("user_id = ?", userId).First(&task).Update("Title", "Buy donuts for Luis") + fmt.Printf("Title: %s\nDueDate: %s\nIsComplete:%t\n\n", + task.Title, task.DueDate, task.IsComplete) + } + + // Delete all the tasks for a user + func DeleteSomeonesTasks(db *gorm.DB, userId int){ + db.Where("user_id = ?", userId).Delete(&Task{}) + fmt.Printf("Deleted all tasks for user %d", userId) + } + + func main() { + connectionString := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s", + server, user, password, database) + db, err := gorm.Open("mssql", connectionString) + + if err != nil { + log.Fatal("Failed to create connection pool. Error: " + err.Error()) + } + gorm.DefaultCallback.Create().Remove("mssql:set_identity_insert") + defer db.Close() + + fmt.Println("Migrating models...") + db.AutoMigrate(&User{}) + db.AutoMigrate(&Task{}) + + // Create awesome Users + fmt.Println("Creating awesome users...") + db.Create(&User{FirstName: "Andrea", LastName: "Lam"}) //UserID: 1 + db.Create(&User{FirstName: "Meet", LastName: "Bhagdev"}) //UserID: 2 + db.Create(&User{FirstName: "Luis", LastName: "Bosquez"}) //UserID: 3 + + // Create appropriate Tasks for each user + fmt.Println("Creating new appropriate tasks...") + db.Create(&Task{ + Title: "Do laundry", DueDate: "2021-03-30", IsComplete: false, UserID: 1}) + db.Create(&Task{ + Title: "Mow the lawn", DueDate: "2021-03-30", IsComplete: false, UserID: 2}) + db.Create(&Task{ + Title: "Do more laundry", DueDate: "2021-03-30", IsComplete: false, UserID: 3}) + db.Create(&Task{ + Title: "Watch TV", DueDate: "2021-03-30", IsComplete: false, UserID: 3}) + + // Read + fmt.Println("\nReading all the tasks...") + ReadAllTasks(db) + + // Update - update Task title to something more appropriate + fmt.Println("Updating Andrea's task...") + UpdateSomeonesTask(db, 1) + + // Delete - delete Luis's task + DeleteSomeonesTasks(db, 3) + } \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/java/Readme.md new file mode 100644 index 0000000000..dbbf92b3c4 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Readme.md @@ -0,0 +1,7 @@ +# Developing applications with Java and Azure SQL + +Pick a platform below to get started: +* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based) +* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows) + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/App.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/App.java new file mode 100644 index 0000000000..19d1b718d2 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/App.java @@ -0,0 +1,117 @@ +package com.sqlsamples; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; + +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +public class App { + + public static void main(String[] args) { + + System.out.println("*** Azure SQL Columnstore demo ***"); + + // Get the key vault secret + // + System.out.println("Fetching Secret from Key Vault."); + SecretClient secretClient = new SecretClientBuilder() + .vaultUrl("https://your_keyvault_name.vault.azure.net/") // Update me + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + KeyVaultSecret secret = secretClient.getSecret("AppSecret"); + System.out.println("Secret Fetched."); + + // Update the connection information below + String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue(); + + // Load SQL Server JDBC driver and establish connection. + try { + // Load SQL Server JDBC driver and establish connection. + System.out.print("Connecting to Azure SQL ... "); + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + + // Create an example database + System.out.print("Dropping Table if already created ... "); + String sql = "DROP TABLE IF EXISTS [Table_with_3M_rows];"; + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + // Insert 3 million rows into the table 'Table_with_3M_rows' + System.out.print( + "Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... "); + sql = new StringBuilder() + .append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))") + .append("SELECT TOP(5000000)").append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId ") + .append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId ") + .append(",a.a * 10 AS Price ") + .append(",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 ") + .append("INTO Table_with_3M_rows ") + .append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;").toString(); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // Execute SQL query without a columnstore index + long elapsedTimeWithoutIndex = SumPrice(connection); + System.out.println("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms"); + + System.out.print("Adding a columnstore to table 'Table_with_3M_rows' ... "); + sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;"; + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // Execute the same SQL query again after the columnstore index + // is added + long elapsedTimeWithIndex = SumPrice(connection); + System.out.println("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms"); + + // Calculate performance gain from adding columnstore index + System.out.println("Performance improvement with columnstore index: " + + elapsedTimeWithoutIndex / elapsedTimeWithIndex + "x!"); + + connection.close(); + } + } catch (Exception e) { + System.out.println(""); + e.printStackTrace(); + } + finally { + + try (Connection connection = DriverManager.getConnection(connectionUrl)){ + // Delete the Employees table if it exists + Statement statement = connection.createStatement(); + statement.executeUpdate("Drop table if exists Table_with_3M_rows"); + System.out.println("Table cleaned up."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + } + + public static long SumPrice(Connection connection) { + String sql = "SELECT SUM(Price) FROM Table_with_3M_rows;"; + long startTime = System.currentTimeMillis(); + try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + long elapsedTime = System.currentTimeMillis() - startTime; + return elapsedTime; + } + } catch (Exception e) { + System.out.println(""); + e.printStackTrace(); + } + return 0; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/pom.xml b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/pom.xml new file mode 100644 index 0000000000..7fcf087457 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlColumnstoreSample/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + com.sqlsamples + AzureSqlColumnstoreSample + jar + 1.0.0 + AzureSqlColumnstoreSample + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + com.microsoft.sqlserver + mssql-jdbc + 7.0.0.jre8 + + + + com.azure + azure-security-keyvault-secrets + 4.0.1 + + + com.azure + azure-security-keyvault-keys + 4.0.0 + + + com.azure + azure-identity + 1.0.4 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + + + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/App.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/App.java new file mode 100644 index 0000000000..298f51bebc --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/App.java @@ -0,0 +1,169 @@ +package com.sqlsamples; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.DriverManager; +import java.text.SimpleDateFormat; +import java.util.List; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; + +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +/** + * Java CRUD sample with Hibernate and Azure SQL + * + */ +public class App { + String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net"; // update me + String userName = "your_user"; // update me + String password = "Will_Be_Updated_From_Key_Vault"; + String sampleDatabaseName = "your_db"; // update me + + // Main entry point + public static void main(String[] args) { + App app = new App(); + app.runDemo(); + } + + // Helper to run the demp app + public void runDemo() + { + // Get the key vault secret + // + System.out.println("Fetching Secret from Key Vault."); + SecretClient secretClient = new SecretClientBuilder() + .vaultUrl("https://your_key_vault.vault.azure.net/") // Update me + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + KeyVaultSecret secret = secretClient.getSecret("AppSecret"); + password = secret.getValue(); + System.out.println("Secret Fetched."); + + // Configure Hibernate logging to only log SEVERE errors + @SuppressWarnings("unused") + org.jboss.logging.Logger logger = org.jboss.logging.Logger.getLogger("org.hibernate"); + java.util.logging.Logger.getLogger("org.hibernate").setLevel(java.util.logging.Level.SEVERE); + + System.out.println("**Java CRUD sample with Hibernate and Azure SQL **\n"); + try { + // We're creating the Hibernate configuration via code. An alternative is to use a 'hibernate.cfg.xml' file. + Configuration cfg = createHibernateConfiguration(); + + // We're mapping POJO classes to Tables via Hibernate Annotations. An alternative is to use Hibernate mapping xml files. + cfg.addAnnotatedClass(User.class); + cfg.addAnnotatedClass(Task.class); + + System.out.println("added classes to config"); + + + // Hibernate needs an existing database. We already have one created. + + // Create the Hibernate SessionFactory and Session. + // This causes Hibernate to create Tables and Relationships in the database from our Annotated classes. + try (SessionFactory sessionFactory = cfg.buildSessionFactory(); + Session session = sessionFactory.openSession()) { + + System.out.println("Created database schema from Java classes.\n"); + session.beginTransaction(); + + // Create demo: Create a User instance and save it to the database + User newUser = new User("Anna", "Shrestinian"); + session.save(newUser); + System.out.println("Created User: " + newUser.toString()); + + // Create demo: Create a Task instance and save it to the database + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy"); + Task newTask = new Task("Ship Helsinki", sdf.parse("04-01-2017")); + session.save(newTask); + System.out.println("Created Task: " + newTask.toString()); + + // Association demo: Assign task to user + newTask.setUser(newUser); + session.save(newTask); + System.out.println("Assigned Task: '" + newTask.getTitle() + "' to user '" + newUser.getFullName() + "'\n"); + + // Read demo: find incomplete tasks assigned to user 'Anna' + System.out.println("Incomplete tasks assigned to 'Anna':"); + String hqlQuery = "from Task where isComplete = false and user.firstName = :paramFirstName"; + List incompleteTasks = session.createQuery(hqlQuery, Task.class) + .setParameter("paramFirstName", "Anna") + .getResultList(); + for(Task theTask : incompleteTasks) { + System.out.println(theTask.toString()); + } + + // Update demo: change the 'dueDate' of a task + hqlQuery = "from Task"; + Task taskToUpdate = session.createQuery(hqlQuery, Task.class) + .getResultList() + .get(0); // get the first task + System.out.println("\nUpdating task: " + taskToUpdate.toString()); + taskToUpdate.setDueDate(sdf.parse("06-30-2016")); + session.save(taskToUpdate); + System.out.println("dueDate changed: " + taskToUpdate.toString()); + + // Delete demo: delete all tasks with a dueDate in 2016 + System.out.println("\nDeleting all tasks with a dueDate in 2016"); + hqlQuery = "from Task where dueDate < :paramDate"; + List tasksToDelete = session.createQuery(hqlQuery, Task.class) + .setParameter("paramDate", sdf.parse("12-31-2016")) + .getResultList(); + for(Task theTask : tasksToDelete) { + System.out.println("Deleting task:" + theTask.toString()); + session.delete(theTask); + } + + // Show tasks after the 'Delete' operation - there should be 0 tasks + System.out.println("\nTasks after delete:"); + hqlQuery = "from Task"; + List tasksAfterDelete = session.createQuery(hqlQuery, Task.class) + .getResultList(); + if(tasksAfterDelete.isEmpty()) { + System.out.println("[None]"); + } + else { + for(Task theTask : tasksAfterDelete) { + System.out.println(theTask.toString()); + } + } + + session.getTransaction().commit(); + } + System.out.println("All done."); + + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + + // Create Hibernate configuration via code instead of using a + // 'hibernate.cfg.xml' file. + private Configuration createHibernateConfiguration() { + String url = this.connectionUrl + ";databaseName=" + this.sampleDatabaseName; + Configuration cfg = new Configuration() + .setProperty("hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver") + .setProperty("hibernate.connection.url", url) + .setProperty("hibernate.connection.username", this.userName) + .setProperty("hibernate.connection.password", this.password) + .setProperty("hibernate.connection.autocommit", "true") + .setProperty("hibernate.show_sql", "false"); + + // Tell Hibernate to use the 'SQL Server' dialect when dynamically + // generating SQL queries + cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect"); + + // Tell Hibernate to show the generated T-SQL + cfg.setProperty("hibernate.show_sql", "false"); + + // This is ok during development, but not recommended in production + // See: http://stackoverflow.com/questions/221379/hibernate-hbm2ddl-auto-update-in-production + cfg.setProperty("hibernate.hbm2ddl.auto", "update"); + return cfg; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/Task.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/Task.java new file mode 100644 index 0000000000..4e2d9e045c --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/Task.java @@ -0,0 +1,77 @@ +package com.sqlsamples; + +import java.util.Date; +import javax.persistence.*; +import java.text.SimpleDateFormat; + +@Entity +@Table(name = "Tasks") +public class Task { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", updatable = false, nullable = false) + private Long id; + private String title; + private Boolean isComplete; + @Temporal(TemporalType.TIMESTAMP) + private Date dueDate; + + // Specify a Many:1 mapping between Task and User + @ManyToOne + private User user; + + public Task() { + } + + public Task(String title, Date dueDate) { + this.title = title; + this.dueDate = dueDate; + this.isComplete = false; + } + + public Task(String title, Date dueDate, User user) { + this.title = title; + this.dueDate = dueDate; + this.isComplete = false; + this.user = user; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public User getUser() { + return this.user; + } + + public void setUser(User user) { + this.user = user; + } + + public Date getDueDate() { + return this.dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + @Override + public String toString() { + SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); + return "Task [id=" + this.id + ", title=" + this.title + ", dueDate=" + ft.format(this.dueDate) + + ", isComplete=" + this.isComplete.toString() + "]"; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/User.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/User.java new file mode 100644 index 0000000000..c57132b5fb --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/User.java @@ -0,0 +1,70 @@ +package com.sqlsamples; + +import java.util.List; +import java.util.ArrayList; +import javax.persistence.*; + +@Entity +@Table(name = "Users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", updatable = false, nullable = false) + private Long id; + private String firstName; + private String lastName; + + // Specify a 1:Many mapping between User and Task via the "user" field in + // the "Tasks" class. + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List tasks = new ArrayList(); + + public User() { + } + + public User(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFullName() { + return this.firstName + " " + this.lastName; + } + + public List getTasks() { + return tasks; + } + + public void setTasks(List tasks) { + this.tasks = tasks; + } + + @Override + public String toString() { + return "User [id=" + this.id + ", name=" + this.getFullName() + "]"; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/pom.xml b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/pom.xml new file mode 100644 index 0000000000..7183584e12 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlHibernateSample/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + com.sqlsamples + AzureSqlHibernateSample + jar + 1.0.0 + AzureSqlHibernateSample + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + com.microsoft.sqlserver + mssql-jdbc + 7.0.0.jre8 + + + + org.hibernate + hibernate-core + 5.2.3.Final + + + org.javassist + javassist + 3.23.1-GA + + + javax.xml.bind + jaxb-api + 2.3.0 + + + + com.azure + azure-security-keyvault-secrets + 4.0.1 + + + com.azure + azure-security-keyvault-keys + 4.0.0 + + + com.azure + azure-identity + 1.0.4 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + + UTF-8 + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App.java new file mode 100644 index 0000000000..c97e2ed04f --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App.java @@ -0,0 +1,111 @@ +package com.sqlsamples; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.DriverManager; + +public class App { + + public static void main(String[] args) { + + System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Update the connection information below + String connectionUrl = "jdbc:sqlserver://your_server_name.database.windows.net;databaseName=your_database_name;user=your_user;password=your_password"; + + try { + // Load SQL Server JDBC driver and establish connection. + System.out.print("Connecting to Azure SQL ... "); + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + + // Create a sample database + System.out.print("Dropping Employees table if exists ... "); + String sql = "DROP Table IF EXISTS Employees"; + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // Create a Table and insert some sample data + System.out.println("Creating sample table with data, press ENTER to continue..."); + System.in.read(); + sql = new StringBuilder().append("CREATE TABLE Employees ( ") + .append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ") + .append(" Location NVARCHAR(50) ").append("); ") + .append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ") + .append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString(); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // INSERT demo + System.out.println("Inserting a new row into table, press ENTER to continue..."); + System.in.read(); + sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);") + .toString(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, "Jake"); + statement.setString(2, "United States"); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue..."); + System.in.read(); + sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToUpdate); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + System.out.println("Deleting user '" + userToDelete + "', press ENTER to continue..."); + System.in.read(); + sql = "DELETE FROM Employees WHERE Name = ?;"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToDelete); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) deleted"); + } + + // READ demo + System.out.println("Reading data from table, press ENTER to continue..."); + System.in.read(); + sql = "SELECT Id, Name, Location FROM Employees;"; + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + System.out.println( + resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3)); + } + } + connection.close(); + System.out.println("All done."); + } + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } finally { + String sql = "DROP Table IF EXISTS Employees"; + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Table dropped."); + } + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App_KeyVault.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App_KeyVault.java new file mode 100644 index 0000000000..6970f0a7b3 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/App_KeyVault.java @@ -0,0 +1,126 @@ +package com.sqlsamples; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.DriverManager; + +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +public class App { + + public static void main(String[] args) { + + System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Get the key vault secret + // + System.out.println("Fetching Secret from Key Vault."); + SecretClient secretClient = new SecretClientBuilder() + .vaultUrl("https://your_keyvault_name.vault.azure.net/") // Update me + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + KeyVaultSecret secret = secretClient.getSecret("AppSecret"); + System.out.println("Secret Fetched."); + + // Update the connection information below + String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue(); + + try { + // Load Azure SQL JDBC driver and establish connection. + System.out.print("Connecting to Azure SQL ... "); + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + + // Delete the Employees table if it exists + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("Drop table if exists Employees"); + System.out.println("Done."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + + // Create a Table and insert some sample data + System.out.print("Creating sample table with data, press ENTER to continue..."); + System.in.read(); + String sql = new StringBuilder().append("CREATE TABLE Employees ( ") + .append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ") + .append(" Location NVARCHAR(50) ").append("); ") + .append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ") + .append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString(); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // INSERT demo + System.out.print("Inserting a new row into table, press ENTER to continue..."); + System.in.read(); + sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);") + .toString(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, "Jake"); + statement.setString(2, "United States"); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue..."); + System.in.read(); + sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToUpdate); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + System.out.print("Deleting user '" + userToDelete + "', press ENTER to continue..."); + System.in.read(); + sql = "DELETE FROM Employees WHERE Name = ?;"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToDelete); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) deleted"); + } + + // READ demo + System.out.print("Reading data from table, press ENTER to continue..."); + System.in.read(); + sql = "SELECT Id, Name, Location FROM Employees;"; + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + System.out.println( + resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3)); + } + } + connection.close(); + System.out.println("All done."); + } + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + finally { + + try (Connection connection = DriverManager.getConnection(connectionUrl)){ + // Delete the Employees table if it exists + Statement statement = connection.createStatement(); + statement.executeUpdate("Drop table if exists Employees"); + System.out.println("Table cleaned up."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/pom.xml b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/pom.xml new file mode 100644 index 0000000000..eaae13dbfb --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/AzureSqlSample/pom.xml @@ -0,0 +1,99 @@ + + + + 4.0.0 + + com.sqlsamples + AzureSqlSample + 1.0.0 + + AzureSqlSample + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + test + + + com.microsoft.sqlserver + mssql-jdbc + 7.0.0.jre8 + + + com.azure + azure-security-keyvault-secrets + 4.0.1 + + + + com.azure + azure-security-keyvault-keys + 4.0.0 + + + com.azure + azure-identity + 1.0.4 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/Readme.md new file mode 100644 index 0000000000..833e7e9570 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Unix-based/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [Java tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/App.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/App.java new file mode 100644 index 0000000000..19d1b718d2 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/App.java @@ -0,0 +1,117 @@ +package com.sqlsamples; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; + +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +public class App { + + public static void main(String[] args) { + + System.out.println("*** Azure SQL Columnstore demo ***"); + + // Get the key vault secret + // + System.out.println("Fetching Secret from Key Vault."); + SecretClient secretClient = new SecretClientBuilder() + .vaultUrl("https://your_keyvault_name.vault.azure.net/") // Update me + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + KeyVaultSecret secret = secretClient.getSecret("AppSecret"); + System.out.println("Secret Fetched."); + + // Update the connection information below + String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue(); + + // Load SQL Server JDBC driver and establish connection. + try { + // Load SQL Server JDBC driver and establish connection. + System.out.print("Connecting to Azure SQL ... "); + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + + // Create an example database + System.out.print("Dropping Table if already created ... "); + String sql = "DROP TABLE IF EXISTS [Table_with_3M_rows];"; + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + // Insert 3 million rows into the table 'Table_with_3M_rows' + System.out.print( + "Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait ... "); + sql = new StringBuilder() + .append("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))") + .append("SELECT TOP(5000000)").append("ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId ") + .append(",a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId ") + .append(",a.a * 10 AS Price ") + .append(",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 ") + .append("INTO Table_with_3M_rows ") + .append("FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;").toString(); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // Execute SQL query without a columnstore index + long elapsedTimeWithoutIndex = SumPrice(connection); + System.out.println("Query time WITHOUT columnstore index: " + elapsedTimeWithoutIndex + "ms"); + + System.out.print("Adding a columnstore to table 'Table_with_3M_rows' ... "); + sql = "CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;"; + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // Execute the same SQL query again after the columnstore index + // is added + long elapsedTimeWithIndex = SumPrice(connection); + System.out.println("Query time WITH columnstore index: " + elapsedTimeWithIndex + "ms"); + + // Calculate performance gain from adding columnstore index + System.out.println("Performance improvement with columnstore index: " + + elapsedTimeWithoutIndex / elapsedTimeWithIndex + "x!"); + + connection.close(); + } + } catch (Exception e) { + System.out.println(""); + e.printStackTrace(); + } + finally { + + try (Connection connection = DriverManager.getConnection(connectionUrl)){ + // Delete the Employees table if it exists + Statement statement = connection.createStatement(); + statement.executeUpdate("Drop table if exists Table_with_3M_rows"); + System.out.println("Table cleaned up."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + } + + public static long SumPrice(Connection connection) { + String sql = "SELECT SUM(Price) FROM Table_with_3M_rows;"; + long startTime = System.currentTimeMillis(); + try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + long elapsedTime = System.currentTimeMillis() - startTime; + return elapsedTime; + } + } catch (Exception e) { + System.out.println(""); + e.printStackTrace(); + } + return 0; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/pom.xml b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/pom.xml new file mode 100644 index 0000000000..7fcf087457 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlColumnstoreSample/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + com.sqlsamples + AzureSqlColumnstoreSample + jar + 1.0.0 + AzureSqlColumnstoreSample + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + com.microsoft.sqlserver + mssql-jdbc + 7.0.0.jre8 + + + + com.azure + azure-security-keyvault-secrets + 4.0.1 + + + com.azure + azure-security-keyvault-keys + 4.0.0 + + + com.azure + azure-identity + 1.0.4 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + + + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/App.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/App.java new file mode 100644 index 0000000000..298f51bebc --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/App.java @@ -0,0 +1,169 @@ +package com.sqlsamples; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.DriverManager; +import java.text.SimpleDateFormat; +import java.util.List; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; + +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +/** + * Java CRUD sample with Hibernate and Azure SQL + * + */ +public class App { + String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net"; // update me + String userName = "your_user"; // update me + String password = "Will_Be_Updated_From_Key_Vault"; + String sampleDatabaseName = "your_db"; // update me + + // Main entry point + public static void main(String[] args) { + App app = new App(); + app.runDemo(); + } + + // Helper to run the demp app + public void runDemo() + { + // Get the key vault secret + // + System.out.println("Fetching Secret from Key Vault."); + SecretClient secretClient = new SecretClientBuilder() + .vaultUrl("https://your_key_vault.vault.azure.net/") // Update me + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + KeyVaultSecret secret = secretClient.getSecret("AppSecret"); + password = secret.getValue(); + System.out.println("Secret Fetched."); + + // Configure Hibernate logging to only log SEVERE errors + @SuppressWarnings("unused") + org.jboss.logging.Logger logger = org.jboss.logging.Logger.getLogger("org.hibernate"); + java.util.logging.Logger.getLogger("org.hibernate").setLevel(java.util.logging.Level.SEVERE); + + System.out.println("**Java CRUD sample with Hibernate and Azure SQL **\n"); + try { + // We're creating the Hibernate configuration via code. An alternative is to use a 'hibernate.cfg.xml' file. + Configuration cfg = createHibernateConfiguration(); + + // We're mapping POJO classes to Tables via Hibernate Annotations. An alternative is to use Hibernate mapping xml files. + cfg.addAnnotatedClass(User.class); + cfg.addAnnotatedClass(Task.class); + + System.out.println("added classes to config"); + + + // Hibernate needs an existing database. We already have one created. + + // Create the Hibernate SessionFactory and Session. + // This causes Hibernate to create Tables and Relationships in the database from our Annotated classes. + try (SessionFactory sessionFactory = cfg.buildSessionFactory(); + Session session = sessionFactory.openSession()) { + + System.out.println("Created database schema from Java classes.\n"); + session.beginTransaction(); + + // Create demo: Create a User instance and save it to the database + User newUser = new User("Anna", "Shrestinian"); + session.save(newUser); + System.out.println("Created User: " + newUser.toString()); + + // Create demo: Create a Task instance and save it to the database + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy"); + Task newTask = new Task("Ship Helsinki", sdf.parse("04-01-2017")); + session.save(newTask); + System.out.println("Created Task: " + newTask.toString()); + + // Association demo: Assign task to user + newTask.setUser(newUser); + session.save(newTask); + System.out.println("Assigned Task: '" + newTask.getTitle() + "' to user '" + newUser.getFullName() + "'\n"); + + // Read demo: find incomplete tasks assigned to user 'Anna' + System.out.println("Incomplete tasks assigned to 'Anna':"); + String hqlQuery = "from Task where isComplete = false and user.firstName = :paramFirstName"; + List incompleteTasks = session.createQuery(hqlQuery, Task.class) + .setParameter("paramFirstName", "Anna") + .getResultList(); + for(Task theTask : incompleteTasks) { + System.out.println(theTask.toString()); + } + + // Update demo: change the 'dueDate' of a task + hqlQuery = "from Task"; + Task taskToUpdate = session.createQuery(hqlQuery, Task.class) + .getResultList() + .get(0); // get the first task + System.out.println("\nUpdating task: " + taskToUpdate.toString()); + taskToUpdate.setDueDate(sdf.parse("06-30-2016")); + session.save(taskToUpdate); + System.out.println("dueDate changed: " + taskToUpdate.toString()); + + // Delete demo: delete all tasks with a dueDate in 2016 + System.out.println("\nDeleting all tasks with a dueDate in 2016"); + hqlQuery = "from Task where dueDate < :paramDate"; + List tasksToDelete = session.createQuery(hqlQuery, Task.class) + .setParameter("paramDate", sdf.parse("12-31-2016")) + .getResultList(); + for(Task theTask : tasksToDelete) { + System.out.println("Deleting task:" + theTask.toString()); + session.delete(theTask); + } + + // Show tasks after the 'Delete' operation - there should be 0 tasks + System.out.println("\nTasks after delete:"); + hqlQuery = "from Task"; + List tasksAfterDelete = session.createQuery(hqlQuery, Task.class) + .getResultList(); + if(tasksAfterDelete.isEmpty()) { + System.out.println("[None]"); + } + else { + for(Task theTask : tasksAfterDelete) { + System.out.println(theTask.toString()); + } + } + + session.getTransaction().commit(); + } + System.out.println("All done."); + + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + + // Create Hibernate configuration via code instead of using a + // 'hibernate.cfg.xml' file. + private Configuration createHibernateConfiguration() { + String url = this.connectionUrl + ";databaseName=" + this.sampleDatabaseName; + Configuration cfg = new Configuration() + .setProperty("hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver") + .setProperty("hibernate.connection.url", url) + .setProperty("hibernate.connection.username", this.userName) + .setProperty("hibernate.connection.password", this.password) + .setProperty("hibernate.connection.autocommit", "true") + .setProperty("hibernate.show_sql", "false"); + + // Tell Hibernate to use the 'SQL Server' dialect when dynamically + // generating SQL queries + cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect"); + + // Tell Hibernate to show the generated T-SQL + cfg.setProperty("hibernate.show_sql", "false"); + + // This is ok during development, but not recommended in production + // See: http://stackoverflow.com/questions/221379/hibernate-hbm2ddl-auto-update-in-production + cfg.setProperty("hibernate.hbm2ddl.auto", "update"); + return cfg; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/Task.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/Task.java new file mode 100644 index 0000000000..4e2d9e045c --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/Task.java @@ -0,0 +1,77 @@ +package com.sqlsamples; + +import java.util.Date; +import javax.persistence.*; +import java.text.SimpleDateFormat; + +@Entity +@Table(name = "Tasks") +public class Task { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", updatable = false, nullable = false) + private Long id; + private String title; + private Boolean isComplete; + @Temporal(TemporalType.TIMESTAMP) + private Date dueDate; + + // Specify a Many:1 mapping between Task and User + @ManyToOne + private User user; + + public Task() { + } + + public Task(String title, Date dueDate) { + this.title = title; + this.dueDate = dueDate; + this.isComplete = false; + } + + public Task(String title, Date dueDate, User user) { + this.title = title; + this.dueDate = dueDate; + this.isComplete = false; + this.user = user; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public User getUser() { + return this.user; + } + + public void setUser(User user) { + this.user = user; + } + + public Date getDueDate() { + return this.dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + @Override + public String toString() { + SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); + return "Task [id=" + this.id + ", title=" + this.title + ", dueDate=" + ft.format(this.dueDate) + + ", isComplete=" + this.isComplete.toString() + "]"; + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/User.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/User.java new file mode 100644 index 0000000000..43fa53554a --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/User.java @@ -0,0 +1,69 @@ +package com.sqlsamples; + +import java.util.List; +import java.util.ArrayList; +import javax.persistence.*; + +@Entity +@Table(name = "Users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", updatable = false, nullable = false) + private Long id; + private String firstName; + private String lastName; + + // Specify a 1:Many mapping between User and Task via the "user" field in + // the "Tasks" class. + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List tasks = new ArrayList(); + + public User() { + } + + public User(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFullName() { + return this.firstName + " " + this.lastName; + } + + public List getTasks() { + return tasks; + } + + public void setTasks(List tasks) { + this.tasks = tasks; + } + + @Override + public String toString() { + return "User [id=" + this.id + ", name=" + this.getFullName() + "]"; + } \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/pom.xml b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/pom.xml new file mode 100644 index 0000000000..7183584e12 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlHibernateSample/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + com.sqlsamples + AzureSqlHibernateSample + jar + 1.0.0 + AzureSqlHibernateSample + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + com.microsoft.sqlserver + mssql-jdbc + 7.0.0.jre8 + + + + org.hibernate + hibernate-core + 5.2.3.Final + + + org.javassist + javassist + 3.23.1-GA + + + javax.xml.bind + jaxb-api + 2.3.0 + + + + com.azure + azure-security-keyvault-secrets + 4.0.1 + + + com.azure + azure-security-keyvault-keys + 4.0.0 + + + com.azure + azure-identity + 1.0.4 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + + UTF-8 + 1.8 + 1.8 + + \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App.java new file mode 100644 index 0000000000..11603560ef --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App.java @@ -0,0 +1,111 @@ +package com.sqlsamples; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.DriverManager; + +public class App { + + public static void main(String[] args) { + + System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Update the connection information below + String connectionUrl = "jdbc:sqlserver://your_server_name.database.windows.net;databaseName=your_database_name;user=your_user;password=your_password"; + + try { + // Load Azure SQL JDBC driver and establish connection. + System.out.print("Connecting to Azure SQL ... "); + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + + // Delete the Employees table if it exists + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("Drop table if exists Employees"); + System.out.println("Done."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + + // Create a Table and insert some sample data + System.out.print("Creating sample table with data, press ENTER to continue..."); + System.in.read(); + String sql = new StringBuilder().append("CREATE TABLE Employees ( ") + .append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ") + .append(" Location NVARCHAR(50) ").append("); ") + .append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ") + .append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString(); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // INSERT demo + System.out.print("Inserting a new row into table, press ENTER to continue..."); + System.in.read(); + sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);") + .toString(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, "Jake"); + statement.setString(2, "United States"); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue..."); + System.in.read(); + sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToUpdate); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + System.out.print("Deleting user '" + userToDelete + "', press ENTER to continue..."); + System.in.read(); + sql = "DELETE FROM Employees WHERE Name = ?;"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToDelete); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) deleted"); + } + + // READ demo + System.out.print("Reading data from table, press ENTER to continue..."); + System.in.read(); + sql = "SELECT Id, Name, Location FROM Employees;"; + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + System.out.println( + resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3)); + } + } + connection.close(); + System.out.println("All done."); + } + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + finally { + + try (Connection connection = DriverManager.getConnection(connectionUrl)){ + // Delete the Employees table if it exists + Statement statement = connection.createStatement(); + statement.executeUpdate("Drop table if exists Employees"); + System.out.println("Table cleaned up."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App_KeyVault.java b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App_KeyVault.java new file mode 100644 index 0000000000..9959a7fc3f --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/App_KeyVault.java @@ -0,0 +1,126 @@ +package com.sqlsamples; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.DriverManager; + +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.security.keyvault.secrets.SecretClient; +import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import com.azure.security.keyvault.secrets.SecretClientBuilder; + +public class App { + + public static void main(String[] args) { + + System.out.println("Connect to Azure SQL and demo Create, Read, Update and Delete operations."); + + // Get the key vault secret + // + System.out.println("Fetching Secret from Key Vault."); + SecretClient secretClient = new SecretClientBuilder() + .vaultUrl("https://your_keyvault_name.vault.azure.net/") + .credential(new DefaultAzureCredentialBuilder().build()) + .buildClient(); + KeyVaultSecret secret = secretClient.getSecret("AppSecret"); + System.out.println("Secret Fetched."); + + // Update the connection information below + String connectionUrl = "jdbc:sqlserver://your_server.database.windows.net;databaseName=your_db;user=your_user;password=" + secret.getValue(); + + try { + // Load Azure SQL JDBC driver and establish connection. + System.out.print("Connecting to Azure SQL ... "); + try (Connection connection = DriverManager.getConnection(connectionUrl)) { + System.out.println("Done."); + + // Delete the Employees table if it exists + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("Drop table if exists Employees"); + System.out.println("Done."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + + // Create a Table and insert some sample data + System.out.print("Creating sample table with data, press ENTER to continue..."); + System.in.read(); + String sql = new StringBuilder().append("CREATE TABLE Employees ( ") + .append(" Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY, ").append(" Name NVARCHAR(50), ") + .append(" Location NVARCHAR(50) ").append("); ") + .append("INSERT INTO Employees (Name, Location) VALUES ").append("(N'Jared', N'Australia'), ") + .append("(N'Nikita', N'India'), ").append("(N'Tom', N'Germany'); ").toString(); + try (Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + System.out.println("Done."); + } + + // INSERT demo + System.out.print("Inserting a new row into table, press ENTER to continue..."); + System.in.read(); + sql = new StringBuilder().append("INSERT Employees (Name, Location) ").append("VALUES (?, ?);") + .toString(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, "Jake"); + statement.setString(2, "United States"); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) inserted"); + } + + // UPDATE demo + String userToUpdate = "Nikita"; + System.out.print("Updating 'Location' for user '" + userToUpdate + "', press ENTER to continue..."); + System.in.read(); + sql = "UPDATE Employees SET Location = N'United States' WHERE Name = ?"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToUpdate); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) updated"); + } + + // DELETE demo + String userToDelete = "Jared"; + System.out.print("Deleting user '" + userToDelete + "', press ENTER to continue..."); + System.in.read(); + sql = "DELETE FROM Employees WHERE Name = ?;"; + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, userToDelete); + int rowsAffected = statement.executeUpdate(); + System.out.println(rowsAffected + " row(s) deleted"); + } + + // READ demo + System.out.print("Reading data from table, press ENTER to continue..."); + System.in.read(); + sql = "SELECT Id, Name, Location FROM Employees;"; + try (Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + while (resultSet.next()) { + System.out.println( + resultSet.getInt(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3)); + } + } + connection.close(); + System.out.println("All done."); + } + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + finally { + + try (Connection connection = DriverManager.getConnection(connectionUrl)){ + // Delete the Employees table if it exists + Statement statement = connection.createStatement(); + statement.executeUpdate("Drop table if exists Employees"); + System.out.println("Table cleaned up."); + } catch (Exception e) { + System.out.println(); + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/pom.xml b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/pom.xml new file mode 100644 index 0000000000..eaae13dbfb --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/AzureSqlSample/pom.xml @@ -0,0 +1,99 @@ + + + + 4.0.0 + + com.sqlsamples + AzureSqlSample + 1.0.0 + + AzureSqlSample + + + UTF-8 + 1.8 + 1.8 + + + + + junit + junit + 4.11 + test + + + com.microsoft.sqlserver + mssql-jdbc + 7.0.0.jre8 + + + com.azure + azure-security-keyvault-secrets + 4.0.1 + + + + com.azure + azure-security-keyvault-keys + 4.0.0 + + + com.azure + azure-identity + 1.0.4 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/Readme.md new file mode 100644 index 0000000000..602463c740 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/java/Windows/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [Java on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/java/windows/az) to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/nodejs/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Readme.md new file mode 100644 index 0000000000..fde37c0305 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Readme.md @@ -0,0 +1,7 @@ +# Developing applications with NodeJs and Azure SQL + +Pick a platform below to get started: +* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based) +* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows) + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlColumnstoreSample/columnstore.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlColumnstoreSample/columnstore.js new file mode 100644 index 0000000000..41443a0798 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlColumnstoreSample/columnstore.js @@ -0,0 +1,99 @@ +var Connection = require('tedious').Connection; +var Request = require('tedious').Request; +var uuid = require('node-uuid'); +var async = require('async'); +const KeyVaultSecrets = require("@azure/keyvault-secrets"); +const Identity = require("@azure/identity"); + +var password; +var conn; + +async function GetSecret(){ + console.log("Getting secret..."); + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new Identity.DefaultAzureCredential(); + + const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name"; + const url = `https://${vaultName}.vault.azure.net`; + + const client = new KeyVaultSecrets.SecretClient(url, credential); + + try { + secret = await client.getSecret('AppSecret').then((secret) => { + password = secret.value; + }); + } + catch (error) { + console.log("Error connecting to key vault: " + error); + } +} + +async function GetConnection(){ + var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: password // will be retrieved + } + }, + options: { + encrypt: true, + trustServerCertificate: true, + database: 'your_database' // update me + } + }; + + conn = new Connection(config); + conn.connect(); +} + +function exec(sql) { + var timerName = "QueryTime"; + + var request = new Request(sql, function(err) { + if (err) { + console.log(err); + } + }); + request.on('doneProc', function(rowCount, more, rows) { + if(!more){ + console.timeEnd(timerName); + } + }); + request.on('row', function(columns) { + columns.forEach(function(column) { + console.log("Sum: " + column.value); + }); + }); + console.time(timerName); + conn.execSql(request); +} + +async function Main() { + + await GetSecret(); + await GetConnection(); + + console.log("Got connection"); + + conn.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + + // Execute all functions in the array serially + async.waterfall([ + function(){ + exec('SELECT SUM(Price) FROM Table_with_3M_rows');}, + ]); + }}); + +} + +Main(); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/connect.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/connect.js new file mode 100644 index 0000000000..4d3673c102 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/connect.js @@ -0,0 +1,32 @@ +var Connection = require('tedious').Connection; + var Request = require('tedious').Request; + var TYPES = require('tedious').TYPES; + + // Create connection to database + var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: 'your_password' // update me + } + }, + options: { + trustServerCertificate: true, + encrypt: true, + database: 'your_database' // update me + + } + } + var connection = new Connection(config); + connection.connect(); + + // Attempt to connect and execute queries if connection goes through + connection.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + } + }); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud.js new file mode 100644 index 0000000000..963be1e7c3 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud.js @@ -0,0 +1,150 @@ +var Connection = require('tedious').Connection; +var Request = require('tedious').Request; +var TYPES = require('tedious').TYPES; +var async = require('async'); + +// Create connection to database +var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: 'your_password' // update me + } + }, + options: { + encrypt: true, + database: 'your_database', // update me + trustServerCertificate: true, + encrypt: true + } +} + +var connection = new Connection(config); +connection.connect(); + +function Start(callback) { + console.log('Starting...'); + callback(null, 'Jake', 'United States'); +} + +function Insert(name, location, callback) { + console.log("Inserting '" + name + "' into Table..."); + + request = new Request( + 'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) inserted'); + callback(null, 'Nikita', 'United States'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Update(name, location, callback) { + console.log("Updating Location to '" + location + "' for '" + name + "'..."); + + // Update the employee record requested + request = new Request( + 'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) updated'); + callback(null, 'Jared'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Delete(name, callback) { + console.log("Deleting '" + name + "' from Table..."); + + // Delete the employee record requested + request = new Request( + 'DELETE FROM TestSchema.Employees WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) deleted'); + callback(null); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + + // Execute SQL statement + connection.execSql(request); +} + +function Read(callback) { + console.log('Reading rows from the Table...'); + + // Read all rows from table + request = new Request( + 'SELECT Id, Name, Location FROM TestSchema.Employees;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) returned'); + callback(null); + } + }); + + // Print the rows read + var result = ""; + request.on('row', function(columns) { + columns.forEach(function(column) { + if (column.value === null) { + console.log('NULL'); + } else { + result += column.value + " "; + } + }); + console.log(result); + result = ""; + }); + + // Execute SQL statement + connection.execSql(request); +} + +function Complete(err, result) { + if (err) { + callback(err); + } else { + console.log("Done!"); + } +} + +// Attempt to connect and execute queries if connection goes through +connection.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + + // Execute all functions in the array serially + async.waterfall([ + Start, + Insert, + Update, + Delete, + Read + ], Complete) + } +}); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud_KeyVault.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud_KeyVault.js new file mode 100644 index 0000000000..e293b6a2c0 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSample/crud_KeyVault.js @@ -0,0 +1,193 @@ +var Connection = require('tedious').Connection; +var Request = require('tedious').Request; +var TYPES = require('tedious').TYPES; +var async = require('async'); +const KeyVaultSecrets = require("@azure/keyvault-secrets"); +const Identity = require("@azure/identity"); + +var pwd; +var connection; + +async function GetSecret(){ + console.log("Getting secret..."); + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new Identity.DefaultAzureCredential(); + + console.log("got default cred"); + + const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name"; + const url = `https://${vaultName}.vault.azure.net`; + + const client = new KeyVaultSecrets.SecretClient(url, credential); + + try { + secret = await client.getSecret('AppSecret').then((secret) => { + pwd = secret.value + }); + } + catch (error) { + console.log("Error connecting to key vault: " + error); + } +} + +async function GetConnection(){ + + // Create connection to database + var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: pwd // fetched from key vault + } + }, + options: { + database: 'your_database', // update me + trustServerCertificate: true, + encrypt: true + } + } + connection = new Connection(config); + await connection.connect(); + console.log("Connected"); + +} + +function Start(callback) { + console.log('Starting...'); + callback(null, 'Jake', 'United States'); +} + +function Insert(name, location, callback) { + console.log("Inserting '" + name + "' into Table..."); + + request = new Request( + 'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) inserted'); + callback(null, 'Nikita', 'United States'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Update(name, location, callback) { + console.log("Updating Location to '" + location + "' for '" + name + "'..."); + + // Update the employee record requested + request = new Request( + 'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) updated'); + callback(null, 'Jared'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Delete(name, callback) { + console.log("Deleting '" + name + "' from Table..."); + + // Delete the employee record requested + request = new Request( + 'DELETE FROM TestSchema.Employees WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) deleted'); + callback(null); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + + // Execute SQL statement + connection.execSql(request); +} + +function Read(callback) { + console.log('Reading rows from the Table...'); + + // Read all rows from table + request = new Request( + 'SELECT Id, Name, Location FROM TestSchema.Employees;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) returned'); + callback(null); + } + }); + + // Print the rows read + var result = ""; + request.on('row', function(columns) { + columns.forEach(function(column) { + if (column.value === null) { + console.log('NULL'); + } else { + result += column.value + " "; + } + }); + console.log(result); + result = ""; + }); + + // Execute SQL statement + connection.execSql(request); +} + +function Complete(err, result) { + if (err) { + throw err; + } else { + console.log("Done!"); + } +} + + +async function Main() { + +// Attempt to connect and execute queries if connection goes through + console.log('Starting'); + + await GetSecret(); + await GetConnection(); + + connection.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + + // Execute all functions in the array serially + async.waterfall([ + Start, + Insert, + Update, + Delete, + Read + ], Complete); + }}); +} + +Main(); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSequelizeSample/orm.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSequelizeSample/orm.js new file mode 100644 index 0000000000..81c9f5d784 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/AzureSqlSequelizeSample/orm.js @@ -0,0 +1,147 @@ + var Sequelize = require('sequelize'); + const KeyVaultSecrets = require("@azure/keyvault-secrets"); + const Identity = require("@azure/identity"); + + + var userName = 'your_user'; // update me + var password = 'fetch_from_key_vault'; // fetched from key vault + var hostName = 'your_server.database.windows.net'; // update me + var sampleDbName = 'your_database'; //update me + + +async function GetSecret(){ + console.log("Getting secret..."); + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new Identity.DefaultAzureCredential(); + + console.log("got default cred"); + + const vaultName = process.env["KEY_VAULT_NAME"] || "your_key_vault_name"; + const url = `https://${vaultName}.vault.azure.net`; + + console.log("connecting to vault: " + vaultName + " at: " + url); + + const client = new KeyVaultSecrets.SecretClient(url, credential); + + try { + secret = await client.getSecret('AppSecret').then((secret) => { + password = secret.value + }); + } + catch (error) { + console.log("Error connecting to key vault: "+ error); + } +} + +async function Main() { + +// Attempt to connect and execute queries if connection goes through + console.log('Starting'); + + await GetSecret(); + + // Initialize Sequelize to connect to sample DB + var sampleDb = new Sequelize(sampleDbName, userName, password, { + dialect: 'mssql', + host: hostName, + port: 1433, // Default port + logging: false, // disable logging; default: console.log, + encrypt: true, + + dialectOptions: { + requestTimeout: 30000 // timeout = 30 seconds + } + }); + + // Define the 'User' model + var User = sampleDb.define('user', { + firstName: Sequelize.STRING, + lastName: Sequelize.STRING + }); + + // Define the 'Task' model + var Task = sampleDb.define('task', { + title: Sequelize.STRING, + dueDate: Sequelize.DATE, + isComplete: Sequelize.BOOLEAN + }); + + // Model a 1:Many relationship between User and Task + User.hasMany(Task); + + console.log('**Node CRUD sample with Sequelize and MSSQL **'); + + // Tell Sequelize to DROP and CREATE tables and relationships in the database + sampleDb.sync({force: true}) + .then(function() { + console.log('\nCreated database schema from model.'); + + // Create demo: Create a User instance and save it to the database + User.create({firstName: 'Anna', lastName: 'Shrestinian'}) + .then(function(user) { + console.log('\nCreated User:', user.get({ plain: true})); + + // Create demo: Create a Task instance and save it to the database + Task.create({ + title: 'Ship Helsinki', dueDate: new Date(2017,04,01), isComplete: false + }) + .then(function(task) { + console.log('\nCreated Task:', task.get({ plain: true})); + + // Association demo: Assign task to user + user.setTasks([task]) + .then(function() { + console.log('\nAssigned task \'' + + task.title + + '\' to user ' + user.firstName + + ' ' + user.lastName); + + // Read demo: find incomplete tasks assigned to user 'Anna'' + User.findAll({ + where: { firstName: 'Anna'}, + include: [{ + model: Task, + where: { isComplete: false } + }] + }) + .then(function(users) { + console.log('\nIncomplete tasks assigned to Anna:\n', + JSON.stringify(users)); + + // Update demo: change the 'dueDate' of a task + Task.findByPk(1).then(function(task) { + console.log('\nUpdating task:', + task.title + ' ' + task.dueDate); + task.update({ + dueDate: new Date(2016,06,30) + }) + .then(function() { + console.log('dueDate changed:', + task.title + ' ' + task.dueDate); + + // Delete demo: delete all tasks with a dueDate in 2016 + console.log('\nDeleting all tasks with with a dueDate in 2016'); + Task.destroy({ + where: { dueDate: {[Sequelize.Op.lte]: new Date(2016,12,31)}}, + }).then(function() { // delete this line and the below, and corresponding closing braces and see what happens. + Task.findAll() + .then(function(tasks) { + console.log('Tasks in database after delete:', + JSON.stringify(tasks)); + console.log('\nAll done!'); + }) + + }) + }) + }) + }) + }) + }) + }) + }) +} + +Main(); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/Readme.md new file mode 100644 index 0000000000..4a64a9fcf1 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Unix-based/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [NodeJs tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlColumnstoreSample/columnstore.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlColumnstoreSample/columnstore.js new file mode 100644 index 0000000000..8bf28bf9b1 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlColumnstoreSample/columnstore.js @@ -0,0 +1,101 @@ +var Connection = require('tedious').Connection; +var Request = require('tedious').Request; +var uuid = require('node-uuid'); +var async = require('async'); +const KeyVaultSecrets = require("@azure/keyvault-secrets"); +const Identity = require("@azure/identity"); + +var password; +var conn; + +async function GetSecret(){ + console.log("Getting secret..."); + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new Identity.DefaultAzureCredential(); + + const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name"; + const url = `https://${vaultName}.vault.azure.net`; + + console.log("connecting to vault: " + vaultName + " at: " + url); + + const client = new KeyVaultSecrets.SecretClient(url, credential); + + try { + secret = await client.getSecret('AppSecret').then((secret) => { + password = secret.value; + }); + } + catch (error) { + console.log("Error connecting to key vault: " + error); + } +} + +async function GetConnection(){ + var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: password // will be retrieved + } + }, + options: { + encrypt: true, + trustServerCertificate: true, + database: 'your_database' // update me + } + }; + + conn = new Connection(config); + conn.connect(); +} + +function exec(sql) { + var timerName = "QueryTime"; + + var request = new Request(sql, function(err) { + if (err) { + console.log(err); + } + }); + request.on('doneProc', function(rowCount, more, rows) { + if(!more){ + console.timeEnd(timerName); + } + }); + request.on('row', function(columns) { + columns.forEach(function(column) { + console.log("Sum: " + column.value); + }); + }); + console.time(timerName); + conn.execSql(request); +} + +async function Main() { + + await GetSecret(); + await GetConnection(); + + console.log("Got connection"); + + conn.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + + // Execute all functions in the array serially + async.waterfall([ + function(){ + exec('SELECT SUM(Price) FROM Table_with_3M_rows');}, + ]); + }}); + +} + +Main(); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/connect.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/connect.js new file mode 100644 index 0000000000..04190829e6 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/connect.js @@ -0,0 +1,31 @@ + var Connection = require('tedious').Connection; + var Request = require('tedious').Request; + var TYPES = require('tedious').TYPES; + + // Create connection to database + var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: 'your_password' // update me + } + }, + options: { + database: 'your_database', // update me + trustServerCertificate: true, + encrypt: true + } + } + var connection = new Connection(config); + connection.connect(); + + // Attempt to connect and execute queries if connection goes through + connection.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + } + }); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud.js new file mode 100644 index 0000000000..e4b08e2c99 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud.js @@ -0,0 +1,147 @@ +var Connection = require('tedious').Connection; +var Request = require('tedious').Request; +var TYPES = require('tedious').TYPES; +var async = require('async'); + +// Create connection to database +var config = { + server: 'your_server.database.windows.net', + authentication: { + type: 'default', + options: { + userName: 'your_user', + password: 'your_password' + } + }, + options: { + database: 'your_database', + trustServerCertificate: true + } +} +var connection = new Connection(config); +connection.connect(); + +function Start(callback) { + console.log('Starting...'); + callback(null, 'Jake', 'United States'); +} + +function Insert(name, location, callback) { + console.log("Inserting '" + name + "' into Table..."); + + request = new Request( + 'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) inserted'); + callback(null, 'Nikita', 'United States'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Update(name, location, callback) { + console.log("Updating Location to '" + location + "' for '" + name + "'..."); + + // Update the employee record requested + request = new Request( + 'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) updated'); + callback(null, 'Jared'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Delete(name, callback) { + console.log("Deleting '" + name + "' from Table..."); + + // Delete the employee record requested + request = new Request( + 'DELETE FROM TestSchema.Employees WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) deleted'); + callback(null); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + + // Execute SQL statement + connection.execSql(request); +} + +function Read(callback) { + console.log('Reading rows from the Table...'); + + // Read all rows from table + request = new Request( + 'SELECT Id, Name, Location FROM TestSchema.Employees;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) returned'); + callback(null); + } + }); + + // Print the rows read + var result = ""; + request.on('row', function(columns) { + columns.forEach(function(column) { + if (column.value === null) { + console.log('NULL'); + } else { + result += column.value + " "; + } + }); + console.log(result); + result = ""; + }); + + // Execute SQL statement + connection.execSql(request); +} + +function Complete(err, result) { + if (err) { + callback(err); + } else { + console.log("Done!"); + } +} + +// Attempt to connect and execute queries if connection goes through +connection.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + + // Execute all functions in the array serially + async.waterfall([ + Start, + Insert, + Update, + Delete, + Read + ], Complete) + } +}); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud_KeyVault.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud_KeyVault.js new file mode 100644 index 0000000000..af51b0868e --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSample/crud_KeyVault.js @@ -0,0 +1,192 @@ +var Connection = require('tedious').Connection; +var Request = require('tedious').Request; +var TYPES = require('tedious').TYPES; +var async = require('async'); +const KeyVaultSecrets = require("@azure/keyvault-secrets"); +const Identity = require("@azure/identity"); + +var pwd; +var connection; + +async function GetSecret(){ + console.log("Getting secret..."); + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new Identity.DefaultAzureCredential(); + + console.log("got default cred"); + + const vaultName = process.env["KEY_VAULT_NAME"] || "your_keyvault_name"; + const url = `https://${vaultName}.vault.azure.net`; + + const client = new KeyVaultSecrets.SecretClient(url, credential); + + try { + secret = await client.getSecret('AppSecret').then((secret) => { + pwd = secret.value + }); + } + catch (error) { + console.log("Error connecting to key vault: " + error); + } +} + +async function GetConnection(){ + + // Create connection to database + var config = { + server: 'your_server.database.windows.net', // update me + authentication: { + type: 'default', + options: { + userName: 'your_user', // update me + password: pwd // fetched from key vault + } + }, + options: { + database: 'your_database', // update me + trustServerCertificate: true, + encrypt: true + } + } + connection = new Connection(config); + await connection.connect(); + console.log("Connected"); +} + +function Start(callback) { + console.log('Starting...'); + callback(null, 'Jake', 'United States'); +} + +function Insert(name, location, callback) { + console.log("Inserting '" + name + "' into Table..."); + + request = new Request( + 'INSERT INTO TestSchema.Employees (Name, Location) OUTPUT INSERTED.Id VALUES (@Name, @Location);', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) inserted'); + callback(null, 'Nikita', 'United States'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Update(name, location, callback) { + console.log("Updating Location to '" + location + "' for '" + name + "'..."); + + // Update the employee record requested + request = new Request( + 'UPDATE TestSchema.Employees SET Location=@Location WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) updated'); + callback(null, 'Jared'); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + request.addParameter('Location', TYPES.NVarChar, location); + + // Execute SQL statement + connection.execSql(request); +} + +function Delete(name, callback) { + console.log("Deleting '" + name + "' from Table..."); + + // Delete the employee record requested + request = new Request( + 'DELETE FROM TestSchema.Employees WHERE Name = @Name;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) deleted'); + callback(null); + } + }); + request.addParameter('Name', TYPES.NVarChar, name); + + // Execute SQL statement + connection.execSql(request); +} + +function Read(callback) { + console.log('Reading rows from the Table...'); + + // Read all rows from table + request = new Request( + 'SELECT Id, Name, Location FROM TestSchema.Employees;', + function(err, rowCount, rows) { + if (err) { + callback(err); + } else { + console.log(rowCount + ' row(s) returned'); + callback(null); + } + }); + + // Print the rows read + var result = ""; + request.on('row', function(columns) { + columns.forEach(function(column) { + if (column.value === null) { + console.log('NULL'); + } else { + result += column.value + " "; + } + }); + console.log(result); + result = ""; + }); + + // Execute SQL statement + connection.execSql(request); +} + +function Complete(err, result) { + if (err) { + throw err; + } else { + console.log("Done!"); + } +} + + +async function Main() { + +// Attempt to connect and execute queries if connection goes through + console.log('Starting'); + + await GetSecret(); + await GetConnection(); + + connection.on('connect', function(err) { + if (err) { + console.log(err); + } else { + console.log('Connected'); + + // Execute all functions in the array serially + async.waterfall([ + Start, + Insert, + Update, + Delete, + Read + ], Complete); + }}); +} + +Main(); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSequelizeSample/orm.js b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSequelizeSample/orm.js new file mode 100644 index 0000000000..314b74cab4 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/AzureSqlSequelizeSample/orm.js @@ -0,0 +1,147 @@ +var Sequelize = require('sequelize'); + const KeyVaultSecrets = require("@azure/keyvault-secrets"); + const Identity = require("@azure/identity"); + + + var userName = 'your_user'; // update me + var password = 'fetch_from_key_vault'; // fetched from key vault + var hostName = 'your_server.database.windows.net'; // update me + var sampleDbName = 'your_database'; //update me + + +async function GetSecret(){ + console.log("Getting secret..."); + // DefaultAzureCredential expects the following three environment variables: + // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory + // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant + // - AZURE_CLIENT_SECRET: The client secret for the registered application + const credential = new Identity.DefaultAzureCredential(); + + console.log("got default cred"); + + const vaultName = process.env["KEYVAULT_NAME"] || "your_key_vault_name"; + const url = `https://${vaultName}.vault.azure.net`; + + console.log("connecting to vault: " + vaultName + " at: " + url); + + const client = new KeyVaultSecrets.SecretClient(url, credential); + + try { + secret = await client.getSecret('AppSecret').then((secret) => { + password = secret.value + }); + } + catch (error) { + console.log("Error connecting to key vault: "+ err); + } +} + +async function Main() { + +// Attempt to connect and execute queries if connection goes through + console.log('Starting'); + + await GetSecret(); + + // Initialize Sequelize to connect to sample DB + var sampleDb = new Sequelize(sampleDbName, userName, password, { + dialect: 'mssql', + host: hostName, + port: 1433, // Default port + logging: false, // disable logging; default: console.log, + encrypt: true, + + dialectOptions: { + requestTimeout: 30000 // timeout = 30 seconds + } + }); + + // Define the 'User' model + var User = sampleDb.define('user', { + firstName: Sequelize.STRING, + lastName: Sequelize.STRING + }); + + // Define the 'Task' model + var Task = sampleDb.define('task', { + title: Sequelize.STRING, + dueDate: Sequelize.DATE, + isComplete: Sequelize.BOOLEAN + }); + + // Model a 1:Many relationship between User and Task + User.hasMany(Task); + + console.log('**Node CRUD sample with Sequelize and MSSQL **'); + + // Tell Sequelize to DROP and CREATE tables and relationships in the database + sampleDb.sync({force: true}) + .then(function() { + console.log('\nCreated database schema from model.'); + + // Create demo: Create a User instance and save it to the database + User.create({firstName: 'Anna', lastName: 'Shrestinian'}) + .then(function(user) { + console.log('\nCreated User:', user.get({ plain: true})); + + // Create demo: Create a Task instance and save it to the database + Task.create({ + title: 'Ship Helsinki', dueDate: new Date(2017,04,01), isComplete: false + }) + .then(function(task) { + console.log('\nCreated Task:', task.get({ plain: true})); + + // Association demo: Assign task to user + user.setTasks([task]) + .then(function() { + console.log('\nAssigned task \'' + + task.title + + '\' to user ' + user.firstName + + ' ' + user.lastName); + + // Read demo: find incomplete tasks assigned to user 'Anna'' + User.findAll({ + where: { firstName: 'Anna'}, + include: [{ + model: Task, + where: { isComplete: false } + }] + }) + .then(function(users) { + console.log('\nIncomplete tasks assigned to Anna:\n', + JSON.stringify(users)); + + // Update demo: change the 'dueDate' of a task + Task.findByPk(1).then(function(task) { + console.log('\nUpdating task:', + task.title + ' ' + task.dueDate); + task.update({ + dueDate: new Date(2016,06,30) + }) + .then(function() { + console.log('dueDate changed:', + task.title + ' ' + task.dueDate); + + // Delete demo: delete all tasks with a dueDate in 2016 + console.log('\nDeleting all tasks with with a dueDate in 2016'); + Task.destroy({ + where: { dueDate: {[Sequelize.Op.lte]: new Date(2016,12,31)}}, + }).then(function() { // delete this line and the below, and corresponding closing braces and see what happens. + Task.findAll() + .then(function(tasks) { + console.log('Tasks in database after delete:', + JSON.stringify(tasks)); + console.log('\nAll done!'); + }) + + }) + }) + }) + }) + }) + }) + }) + }) +} + +Main(); \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/Readme.md new file mode 100644 index 0000000000..b0ef26637b --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/nodejs/Windows/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [NodeJs on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/node/windows/az) to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/php/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/php/Readme.md new file mode 100644 index 0000000000..481816d9cf --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Readme.md @@ -0,0 +1,7 @@ +# Developing applications with PHP and Azure SQL + +Pick a platform below to get started: +* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based) +* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows) + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlColumnstoreSample/columnstore.php b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlColumnstoreSample/columnstore.php new file mode 100644 index 0000000000..1114502fa7 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlColumnstoreSample/columnstore.php @@ -0,0 +1,41 @@ + "your_database", + "Uid" => "your_user", + "PWD" => "your_password" +); +//Establishes the connection +$conn = sqlsrv_connect($serverName, $connectionOptions); + +//Read Query +$tsql= "SELECT SUM(Price) as sum FROM Table_with_3M_rows"; +$getResults= sqlsrv_query($conn, $tsql); +echo ("Sum: "); +if ($getResults == FALSE) + die(FormatErrors(sqlsrv_errors())); +while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) { + echo ($row['sum'] . PHP_EOL); + +} +sqlsrv_free_stmt($getResults); + +function FormatErrors( $errors ) +{ + /* Display errors. */ + echo "Error information: "; + + foreach ( $errors as $error ) + { + echo "SQLSTATE: ".$error['SQLSTATE'].""; + echo "Code: ".$error['code'].""; + echo "Message: ".$error['message'].""; + } +} +$time_end = microtime(true); +$execution_time = round((($time_end - $time_start)*1000),2); +echo 'QueryTime: '.$execution_time.' ms'; + +?> \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/connect.php b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/connect.php new file mode 100644 index 0000000000..020a011c44 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/connect.php @@ -0,0 +1,12 @@ + "your_database", + "Uid" => "your_user", + "PWD" => "your_password" + ); + //Establishes the connection + $conn = sqlsrv_connect($serverName, $connectionOptions); + if($conn) + echo "Connected!" +?> \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/crud.php b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/crud.php new file mode 100644 index 0000000000..c53e9c6637 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/AzureSqlSample/crud.php @@ -0,0 +1,74 @@ + "your_database", + "Uid" => "your_user", + "PWD" => "your_password" +); +//Establishes the connection +$conn = sqlsrv_connect($serverName, $connectionOptions); + +//Insert Query +echo ("Inserting a new row into table" . PHP_EOL); +$tsql= "INSERT INTO TestSchema.Employees (Name, Location) VALUES (?,?);"; +$params = array('Jake','United States'); +$getResults= sqlsrv_query($conn, $tsql, $params); +$rowsAffected = sqlsrv_rows_affected($getResults); +if ($getResults == FALSE or $rowsAffected == FALSE) + die(FormatErrors(sqlsrv_errors())); +echo ($rowsAffected. " row(s) inserted: " . PHP_EOL); + +sqlsrv_free_stmt($getResults); + +//Update Query + +$userToUpdate = 'Nikita'; +$tsql= "UPDATE TestSchema.Employees SET Location = ? WHERE Name = ?"; +$params = array('Sweden', $userToUpdate); +echo("Updating Location for user " . $userToUpdate . PHP_EOL); + +$getResults= sqlsrv_query($conn, $tsql, $params); +$rowsAffected = sqlsrv_rows_affected($getResults); +if ($getResults == FALSE or $rowsAffected == FALSE) + die(FormatErrors(sqlsrv_errors())); +echo ($rowsAffected. " row(s) updated: " . PHP_EOL); +sqlsrv_free_stmt($getResults); + +//Delete Query +$userToDelete = 'Jared'; +$tsql= "DELETE FROM TestSchema.Employees WHERE Name = ?"; +$params = array($userToDelete); +$getResults= sqlsrv_query($conn, $tsql, $params); +echo("Deleting user " . $userToDelete . PHP_EOL); +$rowsAffected = sqlsrv_rows_affected($getResults); +if ($getResults == FALSE or $rowsAffected == FALSE) + die(FormatErrors(sqlsrv_errors())); +echo ($rowsAffected. " row(s) deleted: " . PHP_EOL); +sqlsrv_free_stmt($getResults); + + +//Read Query +$tsql= "SELECT Id, Name, Location FROM TestSchema.Employees;"; +$getResults= sqlsrv_query($conn, $tsql); +echo ("Reading data from table" . PHP_EOL); +if ($getResults == FALSE) + die(FormatErrors(sqlsrv_errors())); +while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) { + echo ($row['Id'] . " " . $row['Name'] . " " . $row['Location'] . PHP_EOL); + +} +sqlsrv_free_stmt($getResults); + +function FormatErrors( $errors ) +{ + /* Display errors. */ + echo "Error information: "; + + foreach ( $errors as $error ) + { + echo "SQLSTATE: ".$error['SQLSTATE'].""; + echo "Code: ".$error['code'].""; + echo "Message: ".$error['message'].""; + } +} +?> \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/Readme.md new file mode 100644 index 0000000000..c29f0ff864 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Unix-based/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [PHP tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/php/Windows/AzureSqlColumnstoreSample/columnstore.php b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlColumnstoreSample/columnstore.php new file mode 100644 index 0000000000..eb194e068e --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlColumnstoreSample/columnstore.php @@ -0,0 +1,42 @@ + "your_database", + "Uid" => "your_user", + "PWD" => "your_password" +); +//Establishes the connection +$conn = sqlsrv_connect($serverName, $connectionOptions); + +//Read Query +$tsql= "SELECT SUM(Price) as sum FROM Table_with_3M_rows"; +$getResults= sqlsrv_query($conn, $tsql); +echo ("Sum: "); +if ($getResults == FALSE) + die(FormatErrors(sqlsrv_errors())); +while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) { + echo ($row['sum'] . PHP_EOL); + +} +sqlsrv_free_stmt($getResults); + +function FormatErrors( $errors ) +{ + /* Display errors. */ + echo "Error information: "; + + foreach ( $errors as $error ) + { + echo "SQLSTATE: ".$error['SQLSTATE'].""; + echo "Code: ".$error['code'].""; + echo "Message: ".$error['message'].""; + } +} +$time_end = microtime(true); +$execution_time = round((($time_end - $time_start)*1000),2); +echo 'QueryTime: '.$execution_time.' ms'; + + +?> \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/connect.php b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/connect.php new file mode 100644 index 0000000000..020a011c44 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/connect.php @@ -0,0 +1,12 @@ + "your_database", + "Uid" => "your_user", + "PWD" => "your_password" + ); + //Establishes the connection + $conn = sqlsrv_connect($serverName, $connectionOptions); + if($conn) + echo "Connected!" +?> \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/crud.php b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/crud.php new file mode 100644 index 0000000000..2f28f000d5 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/AzureSqlSample/crud.php @@ -0,0 +1,74 @@ + "your_database", + "Uid" => "your_user", + "PWD" => "your_password" +); + +//Establishes the connection +$conn = sqlsrv_connect($serverName, $connectionOptions); + +//Insert Query +echo ("Inserting a new row into table" . PHP_EOL); +$tsql= "INSERT INTO TestSchema.Employees (Name, Location) VALUES (?,?);"; +$params = array('Jake','United States'); +$getResults= sqlsrv_query($conn, $tsql, $params); +$rowsAffected = sqlsrv_rows_affected($getResults); +if ($getResults == FALSE or $rowsAffected == FALSE) + die(FormatErrors(sqlsrv_errors())); +echo ($rowsAffected. " row(s) inserted: " . PHP_EOL); + +sqlsrv_free_stmt($getResults); + +//Update Query + +$userToUpdate = 'Nikita'; +$tsql= "UPDATE TestSchema.Employees SET Location = ? WHERE Name = ?"; +$params = array('Sweden', $userToUpdate); +echo("Updating Location for user " . $userToUpdate . PHP_EOL); + +$getResults= sqlsrv_query($conn, $tsql, $params); +$rowsAffected = sqlsrv_rows_affected($getResults); +if ($getResults == FALSE or $rowsAffected == FALSE) + die(FormatErrors(sqlsrv_errors())); +echo ($rowsAffected. " row(s) updated: " . PHP_EOL); +sqlsrv_free_stmt($getResults); + +//Delete Query +$userToDelete = 'Jared'; +$tsql= "DELETE FROM TestSchema.Employees WHERE Name = ?"; +$params = array($userToDelete); +$getResults= sqlsrv_query($conn, $tsql, $params); +echo("Deleting user " . $userToDelete . PHP_EOL); +$rowsAffected = sqlsrv_rows_affected($getResults); +if ($getResults == FALSE or $rowsAffected == FALSE) + die(FormatErrors(sqlsrv_errors())); +echo ($rowsAffected. " row(s) deleted: " . PHP_EOL); +sqlsrv_free_stmt($getResults); + + +//Read Query +$tsql= "SELECT Id, Name, Location FROM TestSchema.Employees;"; +$getResults= sqlsrv_query($conn, $tsql); +echo ("Reading data from table" . PHP_EOL); +if ($getResults == FALSE) + die(FormatErrors(sqlsrv_errors())); +while ($row = sqlsrv_fetch_array($getResults, SQLSRV_FETCH_ASSOC)) { + echo ($row['Id'] . " " . $row['Name'] . " " . $row['Location'] . PHP_EOL); +} +sqlsrv_free_stmt($getResults); + +function FormatErrors( $errors ) +{ + /* Display errors. */ + echo "Error information: "; + + foreach ( $errors as $error ) + { + echo "SQLSTATE: ".$error['SQLSTATE'].""; + echo "Code: ".$error['code'].""; + echo "Message: ".$error['message'].""; + } +} +?> \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/Readme.md new file mode 100644 index 0000000000..c1e823304f --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/php/Windows/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [PHP on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/windows/az) to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/python/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/python/Readme.md new file mode 100644 index 0000000000..cf712935e1 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Readme.md @@ -0,0 +1,7 @@ +# Developing applications with Python and Azure SQL + +Pick a platform below to get started: +* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based) +* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows) + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlColumnstoreSample/columnstore.py b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlColumnstoreSample/columnstore.py new file mode 100644 index 0000000000..216b5eb8ef --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlColumnstoreSample/columnstore.py @@ -0,0 +1,29 @@ +import pyodbc +import datetime +server = 'your_server.database.windows.net' +database = 'your_database' +username = 'your_user' + + +from azure.identity import DefaultAzureCredential +from azure.keyvault.secrets import SecretClient + +credential = DefaultAzureCredential() + +secret_client = SecretClient(vault_url="https://.vault.azure.net", credential=credential) + +# NOTE: please replace the ("") with the name of the secret in your vault +secret = secret_client.get_secret("AppSecret") + +password = secret.value + +cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) +cursor = cnxn.cursor() +tsql = "SELECT SUM(Price) as sum FROM Table_with_3M_rows" +a = datetime.datetime.now() +with cursor.execute(tsql): + b = datetime.datetime.now() + c = b - a + for row in cursor: + print ('Sum:', str(row[0])) + print ('QueryTime:', c.microseconds, 'ms') \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud.py b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud.py new file mode 100644 index 0000000000..002692c718 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud.py @@ -0,0 +1,37 @@ +import pyodbc +server = 'your_server.database.windows.net' +database = 'your_database' +username = 'your_user' +password = 'your_password' +cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) +cursor = cnxn.cursor() + +print ('Inserting a new row into table') +#Insert Query +tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);" +with cursor.execute(tsql,'Jake','United States'): + print ('Successfully Inserted!') + + +#Update Query +print ('Updating Location for Nikita') +tsql = "UPDATE Employees SET Location = ? WHERE Name = ?" +with cursor.execute(tsql,'Sweden','Nikita'): + print ('Successfully Updated!') + + +#Delete Query +print ('Deleting user Jared') +tsql = "DELETE FROM Employees WHERE Name = ?" +with cursor.execute(tsql,'Jared'): + print ('Successfully Deleted!') + + +#Select Query +print ('Reading data from table') +tsql = "SELECT Name, Location FROM Employees;" +with cursor.execute(tsql): + row = cursor.fetchone() + while row: + print (str(row[0]) + " " + str(row[1])) + row = cursor.fetchone() \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud_KeyVault.py b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud_KeyVault.py new file mode 100644 index 0000000000..1291a8d91d --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/AzureSqlSample/crud_KeyVault.py @@ -0,0 +1,50 @@ +import pyodbc +server = 'your_server.database.windows.net' +database = 'your_database' +username = 'your_user' + +from azure.identity import DefaultAzureCredential +from azure.keyvault.secrets import SecretClient + +credential = DefaultAzureCredential() + +secret_client = SecretClient(vault_url="https://.vault.azure.net", credential=credential) + +# NOTE: please replace the ("") with the name of the secret in your vault +secret = secret_client.get_secret("AppSecret") + +password = secret.value + +cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) +cursor = cnxn.cursor() + + +print ('Inserting a new row into table') +#Insert Query +tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);" +with cursor.execute(tsql,'Jake','United States'): + print ('Successfully Inserted!') + + +#Update Query +print ('Updating Location for Nikita') +tsql = "UPDATE Employees SET Location = ? WHERE Name = ?" +with cursor.execute(tsql,'Sweden','Nikita'): + print ('Successfully Updated!') + + +#Delete Query +print ('Deleting user Jared') +tsql = "DELETE FROM Employees WHERE Name = ?" +with cursor.execute(tsql,'Jared'): + print ('Successfully Deleted!') + + +#Select Query +print ('Reading data from table') +tsql = "SELECT Name, Location FROM Employees;" +with cursor.execute(tsql): + row = cursor.fetchone() + while row: + print (str(row[0]) + " " + str(row[1])) + row = cursor.fetchone() \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/Readme.md new file mode 100644 index 0000000000..1b73b75d9e --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Unix-based/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [Python tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started) and select RHEL, Ubuntu, SLES, or macOs to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/python/Windows/AzureSqlColumnstoreSample/columnstore.py b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlColumnstoreSample/columnstore.py new file mode 100644 index 0000000000..216b5eb8ef --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlColumnstoreSample/columnstore.py @@ -0,0 +1,29 @@ +import pyodbc +import datetime +server = 'your_server.database.windows.net' +database = 'your_database' +username = 'your_user' + + +from azure.identity import DefaultAzureCredential +from azure.keyvault.secrets import SecretClient + +credential = DefaultAzureCredential() + +secret_client = SecretClient(vault_url="https://.vault.azure.net", credential=credential) + +# NOTE: please replace the ("") with the name of the secret in your vault +secret = secret_client.get_secret("AppSecret") + +password = secret.value + +cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) +cursor = cnxn.cursor() +tsql = "SELECT SUM(Price) as sum FROM Table_with_3M_rows" +a = datetime.datetime.now() +with cursor.execute(tsql): + b = datetime.datetime.now() + c = b - a + for row in cursor: + print ('Sum:', str(row[0])) + print ('QueryTime:', c.microseconds, 'ms') \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud.py b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud.py new file mode 100644 index 0000000000..64ee10827e --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud.py @@ -0,0 +1,37 @@ +import pyodbc +server = 'your_server.database.windows.net' +database = 'your_database' +username = 'your_user' +password = 'your_password' +cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) +cursor = cnxn.cursor() + +print ('Inserting a new row into table') +#Insert Query +tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);" +with cursor.execute(tsql,'Jake','United States'): + print ('Successfully Inserted!') + + +#Update Query +print ('Updating Location for Nikita') +tsql = "UPDATE Employees SET Location = ? WHERE Name = ?" +with cursor.execute(tsql,'Sweden','Nikita'): + print ('Successfully Updated!') + + +#Delete Query +print ('Deleting user Jared') +tsql = "DELETE FROM Employees WHERE Name = ?" +with cursor.execute(tsql,'Jared'): + print ('Successfully Deleted!') + + +#Select Query +print ('Reading data from table') +tsql = "SELECT Name, Location FROM Employees;" +with cursor.execute(tsql): + row = cursor.fetchone() + while row: + print (str(row[0]) + " " + str(row[1])) + row = cursor.fetchone() \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud_KeyVault.py b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud_KeyVault.py new file mode 100644 index 0000000000..1291a8d91d --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/AzureSqlSample/crud_KeyVault.py @@ -0,0 +1,50 @@ +import pyodbc +server = 'your_server.database.windows.net' +database = 'your_database' +username = 'your_user' + +from azure.identity import DefaultAzureCredential +from azure.keyvault.secrets import SecretClient + +credential = DefaultAzureCredential() + +secret_client = SecretClient(vault_url="https://.vault.azure.net", credential=credential) + +# NOTE: please replace the ("") with the name of the secret in your vault +secret = secret_client.get_secret("AppSecret") + +password = secret.value + +cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password) +cursor = cnxn.cursor() + + +print ('Inserting a new row into table') +#Insert Query +tsql = "INSERT INTO Employees (Name, Location) VALUES (?,?);" +with cursor.execute(tsql,'Jake','United States'): + print ('Successfully Inserted!') + + +#Update Query +print ('Updating Location for Nikita') +tsql = "UPDATE Employees SET Location = ? WHERE Name = ?" +with cursor.execute(tsql,'Sweden','Nikita'): + print ('Successfully Updated!') + + +#Delete Query +print ('Deleting user Jared') +tsql = "DELETE FROM Employees WHERE Name = ?" +with cursor.execute(tsql,'Jared'): + print ('Successfully Deleted!') + + +#Select Query +print ('Reading data from table') +tsql = "SELECT Name, Location FROM Employees;" +with cursor.execute(tsql): + row = cursor.fetchone() + while row: + print (str(row[0]) + " " + str(row[1])) + row = cursor.fetchone() \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/Readme.md new file mode 100644 index 0000000000..f12820ae6a --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/python/Windows/Readme.md @@ -0,0 +1,11 @@ +## Sample details + +Please visit the [Python on Windows tutorial](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/windows/az) to run through the sample in full with more detail. + + + +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/AzureSqlGettingStartedSamples/ruby/AzureSqlColumnstoreSample/columnstore.rb b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlColumnstoreSample/columnstore.rb new file mode 100644 index 0000000000..f4e5b0fecb --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlColumnstoreSample/columnstore.rb @@ -0,0 +1,53 @@ +require 'tiny_tds' +@client = TinyTds::Client.new username: 'your_user@your_server', password: 'your_password', + dataserver: 'your_server.database.windows.net', database: 'your_database', azure: true, timeout: 600 + + +# Calculate time difference in milliseconds +def time_diff_milli(start, finish) + ((finish - start) * 1000).floor +end + +def execute(sql) + @client.execute(sql).do + true +end + +# Ensure the table doesn't already exist. +puts "Drop the table if it exists" +execute("Drop table if exists Table_with_3M_rows") + +# Insert 3 million rows into the table 'Table_with_3M_rows' +puts "Inserting 3 million rows into table 'Table_with_3M_rows'. This takes ~1 minute, please wait." +execute("WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a)) + SELECT TOP(3000000) + 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_3M_rows + FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;") + +# Execute query without columnstore index +t1 = Time.now +execute("SELECT SUM(Price) as sum FROM Table_with_3M_rows") +t2 = Time.now +elapsedTimeWithoutIndex = time_diff_milli t1, t2 +puts "Query time without columnstore index: #{elapsedTimeWithoutIndex}ms" + +# Create columnnstore index on table 'Table_with_3M_rows' +puts("Adding a columnstore index to table 'Table_with_3M_rows'") +execute("CREATE CLUSTERED COLUMNSTORE INDEX columnstoreindex ON Table_with_3M_rows;") + +# Execute the same query with columnstore index +t3 = Time.now +execute("SELECT SUM(Price) as sum FROM Table_with_3M_rows") +t4 = Time.now +elapsedTimeWithIndex = time_diff_milli t3, t4 +puts "Query time WITH columnstore index: #{elapsedTimeWithIndex}ms" + +# Calculate performance improvement with columnstore index +perf_improvement = (elapsedTimeWithoutIndex / elapsedTimeWithIndex).floor +puts "Performance improvement with columnstore index: #{perf_improvement}x!" + +@client.close \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/activerecordcrud.rb b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/activerecordcrud.rb new file mode 100644 index 0000000000..d73eb2c05d --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/activerecordcrud.rb @@ -0,0 +1,56 @@ +require 'active_record' +require 'tiny_tds' +require 'activerecord-sqlserver-adapter' +require 'pp' + +ActiveRecord::Base.establish_connection( + :adapter=> "sqlserver", + :host => "localhost", + :username => "sa", + :password => "your_password" +) + +#Create new database SampleDB +puts "Drop and create new database 'SampleDB'" +ActiveRecord::Base.connection.drop_database('SampleDB') rescue nil +ActiveRecord::Base.connection.create_database('SampleDB') +ActiveRecord::Base.connection.use_database('SampleDB') + +#Create a new table called Tasks +ActiveRecord::Schema.define do + create_table :tasks, force: true do |t| + t.string :taskname + t.string :user + t.date :duedate + end +end + +class Task < ActiveRecord::Base +end + +#Create new tasks and users +Task.create!(taskname:'Install SQL Server 2017 on Windows', user:'Andrea', duedate: '2017-07-01') +Task.create!(taskname:'Upgrade from SQL Server 2014 to 2017', user:'Meet', duedate: '2017-07-01') +Task.create!(taskname:'Write new SQL Server content', user:'Luis', duedate: '2017-07-01') +pp "Created new tasks:" +pp Task.all + +#Update due date for specific task +task_to_update = Task.where(taskname: 'Install SQL Server 2017 on Windows').where(user: 'Andrea').first +puts "Updating the following task:" +pp task_to_update +task_to_update.update_attribute(:duedate, '2017-07-31') +puts "Due date changed:" +pp task_to_update + +#Destroy all tasks for specific user +tasks_to_delete = Task.where(user: 'Meet').first +puts "Deleting all tasks for user:" +pp tasks_to_delete +tasks_to_delete.destroy! + +#Read all tasks +puts "Printing all tasks:" +pp Task.all + +ActiveRecord::Base.connection.close \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/connect.rb b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/connect.rb new file mode 100644 index 0000000000..fc81c2764a --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/connect.rb @@ -0,0 +1,9 @@ + require 'tiny_tds' +@client = TinyTds::Client.new username: 'your_user@your_server', password: 'your_password', + dataserver: 'your_server.database.windows.net', database: 'your_database', azure: true + +puts 'Connecting to Azure SQL' + +if @client.active? == true then puts 'Done' end + +@client.close \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/crud.rb b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/crud.rb new file mode 100644 index 0000000000..e3173e742e --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/AzureSqlSample/crud.rb @@ -0,0 +1,45 @@ +require 'tiny_tds' +@client = TinyTds::Client.new username: 'sa', password: 'your_password', + host: 'localhost', port: 1433 +puts 'Connecting to SQL Server' + +if @client.active? == true then puts 'Done' end + +def execute(sql) + result = @client.execute(sql) + result.each + if result.affected_rows > 0 then puts "#{result.affected_rows} row(s) affected" end +end + +# Create database SampleDB +puts "Dropping and creating database 'SampleDB'" +execute("DROP DATABASE IF EXISTS [SampleDB]; CREATE DATABASE [SampleDB];") + +# Create sample table with data +puts "Creating sample table with data" +execute("USE SampleDB; 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'Jared', N'Australia'), + (N'Nikita', N'India'), (N'Tom', N'Germany')") + +# Insert new employee +puts "Inserting new employee Jake into Employees table" +execute("INSERT INTO Employees (Name, Location) VALUES (N'Jake', N'United States')") + +# Update location for employee +puts "Updating Location for Nikita" +execute("UPDATE Employees SET Location = N'United States' WHERE NAME = N'Nikita'") + +# Delete employee +puts "Deleting employee Jared" +execute("DELETE FROM Employees WHERE NAME = N'Jared'") + +# Read all employees +puts "Reading data from table" +@client.execute("SELECT * FROM Employees").each do |row| + puts row +end + +puts "All done." + +@client.close \ No newline at end of file diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/ruby/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/Readme.md new file mode 100644 index 0000000000..90902b1c65 --- /dev/null +++ b/samples/tutorials/AzureSqlGettingStartedSamples/ruby/Readme.md @@ -0,0 +1,4 @@ +# Developing applications with Ruby and Azure SQL + + +Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file From 70bc287a908eb875ce6efc092031cf02ba80327d Mon Sep 17 00:00:00 2001 From: akatesmith Date: Tue, 15 Sep 2020 12:23:39 -0700 Subject: [PATCH 3/3] forgot to commit the csharp readme --- .../tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md index 2508e863a8..0c7a28ee0e 100644 --- a/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md +++ b/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Readme.md @@ -1,7 +1,7 @@ # Developing applications with C# and Azure SQL Pick a platform below to get started: -* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](linktodo) -* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/java/Windows) +* [unix-based (Includes macOS, RHEL, Ubuntu, SLES](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Unix-based) +* [Windows](https://github.com/Microsoft/sql-server-samples/tree/master/samples/tutorials/AzureSqlGettingStartedSamples/csharp/Windows) Please visit our [getting started tutorials](https://www.microsoft.com/en-us/sql-server/developer-get-started/) \ No newline at end of file