I'm trying to write a Azure Webjob to insert a record into a Azure SQL.
Here is my code:
using System;
using System.Configuration;
using System.Data.SqlClient;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("runing... "+ DateTime.Now.ToString());
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["AzureDB"].ConnectionString;
con.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO [dbo].[myTest] ([CreateTime]) VALUES (GETDATE ( ))", con);
cmd.ExecuteNonQuery();
con.Close();
}
}
}
At the beginning, I just had a Console.WriteLine code which worked fine but just after adding the codes related to reading the connectionstring and data it failed.
Do we need to upload the ddls?
Azure WebApps do not yet support .NET version 4.6.1. That framework version is not yet installed on the hosting VMs. It should be supported in the next couple months, but isn't yet. In the mean time, if you change your WebJob to target 4.6 it will work.
Related
I'm developing a .NET Core 2.1 application that does not use Entity Framework. But I'm wondering how to read the connection string into the Configuration because the usual method expects a DBContext file (which I do not have because I am note using EF).
If I were using EF, I would normally read the connection string from appsettings.json like this:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
How do I do it without the DBContext?
If you're using simple ado.net, you can't use DBContext. You open a connection and execute your query instead:
NOTE using statement is important here to ensure the connection is disposed/closed properly.
using (SqlConnection connection =
new SqlConnection(Configuration.GetConnectionString("DefaultConnection")))
{
// Create the Command and Parameter objects.
SqlCommand command = new SqlCommand(queryString, connection);
command.Parameters.AddWithValue("#pricePoint", paramValue);
// Open the connection in a try/catch block.
// Create and execute the DataReader, writing the result
// set to the console window.
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}\t{2}",
reader[0], reader[1], reader[2]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
So I have this Azure function that works, and an Azure SQL DB with some data. But I cannot find a decent example to get data from the DB into the function. Surely, crafting a query string and SQLCommand.BeginExecuteReader/EndExecuteReader is not the preferred way, right?
LINQtoSQL perhaps?
Thanks, Bezz
You are free to use any .NET Data Access library that's available for other types of applications: ADO.NET, Entity Framework, Dapper etc.
A simple example:
Use Azure Functions to connect to an Azure SQL Database.
Apparently, it was quite simple. This code did the trick. Although I'm not completely happy with the fact that I'm crafting a query string. For now, it will do.
#r "System.Configuration"
#r "System.Data"
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
var str = ConfigurationManager.ConnectionStrings["sqldb_connection"].ConnectionString;
var caterers = new List<string>();
using (SqlConnection conn = new SqlConnection(str))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "SELECT * FROM Caterers";
cmd.Connection = conn;
reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
caterers.Add(reader.GetString(1));
}
}
conn.Close();
}
return req.CreateResponse(HttpStatusCode.OK, caterers);
}
I plan to use WebJobs as a lightweight substitute for NServiceBus but wanted to first verify that routine SQL Azure Database queries can be made from a triggered WebJob handler? My database access will be through EntityFrameworks.
This SO thread indicates that WebJobs does not support SQL Database but I hope this just means that SQL Database cannot be used as a triggering mechanism for a WebJob handler?
Azure Web Job - How to connect to an Azure MS SQL Database?
I have not found a WebJob sample that issues SQL Database queries but since a WebJob has access to the same app config as the main WebSite I assume database connection details can be made available?
Webjobs are any executable that can run on Azure (so .NET programs will run fine). The triggering mechanism is specific and CANNOT utilize SQL Azure but you can run SQL Azure in your executable code WITHIN the webjob itself.
For Example, this webjob waits for the message 'web-jobs-testing-sql' on 'testwebjobsqueue' before executing the query on the SQL Azure database and writing the results to the text file in the configured storage container:
namespace AzureWebJobs
{
class AzureSqlTest
{
static void Main()
{
JobHost host = new JobHost();
host.RunAndBlock();
}
public static void SyndicateFiles([QueueInput("testwebjobsqueue")] string inputText,
[BlobOutput("temp/WebJobs-log.txt")]TextWriter writer)
{
if (!inputText.StartsWith("web-jobs-testing-"))
return;
writer.WriteLine(String.Format("Starting to do processing for " + inputText + " at {0}", DateTime.Now.ToShortTimeString()));
string storageContainerName = ConfigurationManager.AppSettings["StorageContainerNameTemp"].ToLower();
AzureStorageUtils.ConfigureStorage(storageContainerName);
SQLTest sqlTest = new SQLTest();
sqlTest.RunSqlQuery(inputText, writer);
writer.WriteLine(String.Format("Syndication Finished at {0}", DateTime.Now.ToShortTimeString()));
}
}
class SQLTest
{
public SQLTest()
{
}
public void RunSqlQuery(string queueMessage, TextWriter writer)
{
if (queueMessage == "web-jobs-testing-sql")
{
string connectionString = "Server=tcp:YourDatabaseServerName.database.windows.net,1433;Database=YourDatabaseName;User ID=YourSQLAzureUserID;Password=YourStrongPassword;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;";
SqlConnection sqlConnection1 = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Users";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Data is accessible through the DataReader object here.
while (reader.Read())
{
writer.WriteLine(reader.GetValue(1).ToString());
}
reader.Close();
}
sqlConnection1.Close();
}
}
}
}
Of course it would be best to store your connection string, storage container names, etc. in the configuration settings of your website hosting the webjob (you can do this in the 'app settings' and 'connection strings' sections of the 'configure tab' in the azure portal so you don't have any settings in files accessible on the website).
We do not have a triggers for SqlAzure yet. It is something we would consider opening up by way of opening up extensibility for allowing you to Trigger functions based on different events such as SQL Azure, File System watchers etc.
You can share the ConnectionString that you can share between your site and webjob. The following post captures this Use connectionstring in WebJob on Azure
I need to export data from SQL Server when a specific column is updated and wonder if there is some recommended way to do this?
I have a table with an column 'Activated', when this value is changed to true an export should be trigged.
I soppose I need a trigger that reacts on changes in the 'Activated'. And my two options at present is to call the webservice directly from the trigger or let the trigger insert data in a table that my one service reads from and calls the extern service.
Is any of this ideas preferable or is there any other better solution?
you should check out the SQL Server Service Broker - it can be used to trigger external actions on changes to the data.
one implementation (which I have not used) can be found here: http://lab.arc90.com/2009/02/05/sqlwatcher-ad-hoc-database-change-monitoring/
If you have infrequent changes in data (for example classified values), you can use Query Notifications + SQLDependencies class. Behaind the scene its also uses Service Broker #paul mentioned.
For example, you can have table:
CREATE TABLE dbo.MyTable
(
MyTableID INT not null PRIMARY KEY IDENTITY,
SomeText nvarchar(50)
)
And SQL code (user rights are discussed here):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
SqlDependency.Start("server=<MyServer>;database=<MyDB>;User ID=<user>;Password=<pwd>;Integrated Security=false;");
Console.WriteLine("Started..");
get_msg();
Console.ReadLine();
SqlDependency.Stop("server=<MyServer>;database=<MyDB>;User ID=<user>;Password=<pwd>;Integrated Security=false;");
}
private static void get_msg()
{
using (SqlConnection con =
new SqlConnection("server=<MyServer>;database=<MyDB>;User ID=<user>;Password=<pwd>;Integrated Security=false;"))
{
SqlCommand com = new SqlCommand("SELECT MyTableID, SomeText FROM dbo.MyTable ", con);
SqlDependency dependency = new SqlDependency(com);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
con.Open();
com.ExecuteNonQuery();
}
}
static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
Console.WriteLine("dependency Info = {0}, time: {1}",e.Info, DateTime.Now);
get_msg();
}
}
}
Good afternoon,
Im having some trouble writing a simple script using SMO objects in C# to validate if an object exists and then create it. This code is within a Script Task Component in SSIS. The code executes successfully, however the new database does not show up on my local instance. Any help would be greatly appreciated.
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Collections;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
public void Main()
{
//String DBName = Dts.Variables["TmpViewDBName"].Value.ToString();
//String Instance = Dts.Variables["TmpViewDBInstance"].Value.ToString();
String DBName = "localhost";
String Instance = "TmpViewDB";
Server TmpViewServer = new Server(Instance);
//Windows Auth
TmpViewServer.ConnectionContext.LoginSecure = true;
TmpViewServer.ConnectionContext.Connect();
if (TmpViewServer.Databases[DBName] != null)
{
TmpViewServer.Databases[DBName].Drop();
}
Database TmpViewDB = new Database(TmpViewServer, DBName);
if (TmpViewServer.ConnectionContext.IsOpen)
TmpViewServer.ConnectionContext.Disconnect();
Dts.TaskResult = (int)ScriptResults.Success;
}
I believe you need to add a line to actually create the object. As it stands now, you've only instantiated the object but never actually made the call to the database to create the remote object.
Database TmpViewDB = new Database(TmpViewServer, DBName);
TmpViewDB.Create();