How to use SSIS to read from ActiveMQ Queue? - sql-server

I'm a newbie to SSIS, my current workplace requires that we use SSIS to read from ActiveMQ (hosted service by Amazon) and populate certain SQLServer DB tables.
I've used NiFi to some extent in the past but not SSIS and SSIS 2016 doesn't have an ActiveMQ connectior
After googling around, learnt SSIS-ActiveMQ connection can be achieved using Script component of SSIS.
I can do bit of .net / C# scripting if need be, please advise if theres a template project out there or a how-to-guide to write the Script using NMS .net libraries. Many thanks

After few hours of reading through AMQ documentation, I could do this myself. Below is the complete code which currently works but obviously needs bit of TLC, all suggestions welcome.
using System;
using System.Text;
using System.Data.SqlClient;
using Apache.NMS;
using Serilog;
namespace AMQ_ConsoleApp
{
class Program
{
private const string AMQ_URI = "activemq:ssl://abc.net";
private const string AMQ_Queue = "test";
private const string AMQ_User = "userId";
private const string AMQ_Pwd = "password";
static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
)
.WriteTo.File("AMQ_SSIS_Connector.log"
, rollingInterval: RollingInterval.Day
, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
, retainedFileCountLimit:30
)
.CreateLogger();
try
{ Log.Information("#### BEGIN #####");
IConnectionFactory factory = new NMSConnectionFactory(new Uri(AMQ_URI));
IConnection Q_connection = factory.CreateConnection(AMQ_User, AMQ_Pwd);
ISession Q_session = Q_connection.CreateSession();
Log.Debug("Attempting to connect to Queue {Queue}", AMQ_Queue);
Q_connection.Start();
IDestination destination = Q_session.GetQueue(AMQ_Queue);
IMessageConsumer consumer = Q_session.CreateConsumer(destination);
IMessage message;
while (true)
{
Log.Information("______________________________");
Log.Information("Awaiting new message...");
message = consumer.Receive();
if (message != null)
{
ITextMessage textMessage = message as ITextMessage;
if (!string.IsNullOrEmpty(textMessage.Text))
{
Log.Information("Reading message with ID : " + textMessage.NMSMessageId);
WriteToDB(textMessage);
}
}
}
}
catch (Exception ex)
{
Log.Error(ex.ToString());
throw;
}
//ShutDown(Q_session, Q_connection);
}
public static void WriteToDB(ITextMessage msg)
{
try
{
const string SQL_Datasource = "(localdb)\\LocalDBv14";
const string SQL_InitialCatalog = "Customer";
const string SQL_User = "";
const string SQL_User_Pwd = "";
const string SQL_TargetTable = "TableA";
const string SQL_Schema = "dbo";
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = SQL_Datasource;
builder.InitialCatalog = SQL_InitialCatalog;
builder.IntegratedSecurity = true; // Disable for Named SQLServer A/c
StringBuilder sb_SQL = new StringBuilder();
sb_SQL.Append("INSERT INTO ");
sb_SQL.Append("[");
sb_SQL.Append(SQL_Schema);//
sb_SQL.Append("].[");
sb_SQL.Append(SQL_TargetTable);//
sb_SQL.Append("] (");
sb_SQL.Append("[" + "MessageID" + "]");//Fields
sb_SQL.Append(",[" + "Message" + "]");//Fields
sb_SQL.Append(",[" + "AMQ_URI" + "]");//Fields
sb_SQL.Append(",[" + "AMQ_Queue" + "]");//Fields
sb_SQL.Append(",[" + "AMQ_Type" + "]");//Fields
sb_SQL.Append(",[" + "AMQ_Timestamp" + "]");//Fields
sb_SQL.Append(",[" + "RECORD_INSERTED_AT" + "]");//Fields
sb_SQL.Append(",[" + "RECORD_INSERTED_BY" + "]");//Fields
sb_SQL.Append(") VALUES (");
sb_SQL.Append("'" + msg.NMSMessageId + "'");//Data
sb_SQL.Append(",'" + msg.Text + "'");//Data
sb_SQL.Append(",'" + AMQ_URI + "'");//Data
sb_SQL.Append(",'" + msg.NMSDestination.ToString() + "'");//Data
sb_SQL.Append(",'" + msg.NMSType + "'");//Data
sb_SQL.Append("," + msg.NMSTimestamp );//Data
sb_SQL.Append("," + "getdate()" + "");//Data
sb_SQL.Append(",'" + "SSIS_User" + "'");//Data
sb_SQL.Append(")");
// Connect to SQL
Log.Information("Connecting to SQL Server...{Server}", SQL_Datasource);
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
int ret_rows = 0;
Log.Information("Opening DB Connection...{Connection}", SQL_Datasource+"."+SQL_InitialCatalog+"."+SQL_Schema);
connection.Open();
Log.Information("Inserting data into...{Table}", SQL_TargetTable);
using (SqlCommand command = new SqlCommand(sb_SQL.ToString(), connection))
ret_rows = command.ExecuteNonQuery();
if (ret_rows > 0)
{
Log.Information("Data committed to DB successfully, Inserted {records} records." , ret_rows);
//DequeueMessage(msg);
}
else {
Log.Fatal("Data commit to DB Failed.");
}
Log.Information("Closing DB connection...");
connection.Close();
Log.Information("DB Connection closed.");
}
}
catch (SqlException e)
{
Log.Error(e.ToString());
}
}
private static void DequeueMessage(IMessage message)
{
try
{
message.Acknowledge();
Log.Information("Message with ID {msg} de-queued from AMQ.", message.NMSMessageId);
}
catch (Exception ex)
{
Log.Error(ex.ToString());
}
}
private static void ShutDown(ISession session, IConnection connection)
{
Log.Information("Ending AMQ Session");
session.Close();
Log.Information("Closing AMQ Connection");
connection.Close();
}
}
}

Related

How can I connect to Memgraph from my C# application?

I have data stored in dockerized Memgraph database. How can I connect from my C# app to the database?
You have to use Neo4j.Driver.Simple package which implements a blocking interface around the 'main' driver.
Once you have the latest version of driver installed you can connect to your database using one of the ways.
First way:
using System;
using System.Linq;
using Neo4j.Driver;
namespace MemgraphApp
{
public class Program
{
public static void Main()
{
string message = "Hello, World!";
using var _driver = GraphDatabase.Driver("bolt://localhost:7687", AuthTokens.None);
using var session = _driver.Session();
var greeting = session.WriteTransaction(tx =>
{
var result = tx.Run("CREATE (n:FirstNode) " +
"SET n.message = $message " +
"RETURN 'Node ' + id(n) + ': ' + n.message",
new { message });
return result.Single()[0].As<string>();
});
Console.WriteLine(greeting);
}
}
}
Second way:
using System;
using System.Linq;
using Neo4j.Driver;
namespace MemgraphApp
{
public class Program : IDisposable
{
private readonly IDriver _driver;
public Program(string uri, string user, string password)
{
_driver = GraphDatabase.Driver(uri, AuthTokens.Basic(user, password));
}
public void PrintGreeting(string message)
{
using (var session = _driver.Session())
{
var greeting = session.WriteTransaction(tx =>
{
var result = tx.Run("CREATE (n:FirstNode) " +
"SET n.message = $message " +
"RETURN 'Node ' + id(n) + ': ' + n.message",
new { message });
return result.Single()[0].As<string>();
});
Console.WriteLine(greeting);
}
}
public void Dispose()
{
_driver?.Dispose();
}
public static void Main()
{
using (var greeter = new Program("bolt://localhost:7687", "", ""))
{
greeter.PrintGreeting("Hello, World!");
}
}
}
}
Detailed instructions can be found at https://memgraph.com/docs/memgraph/connect-to-memgraph/drivers/c-sharp.

Unable to Connect SQL Server when using MultiThreading

I am try to connect SQL Server using multi-threading the execute SQL query on tables.
When I try to connect SQL server it's working fine without any issue, but when try to connect using thread mechanism it displaying exception.
Here is my code can exception message please let me know how to resolve this issue.
using System;
using System.Data.SqlClient;
using NUnit.Framework;
using System.Threading;
namespace ThreadSQLConnect
{
[TestFixture]
public class SQLConnect
{
private static object threadLock = new object();
[Test]
public void temp()
{CreateThread(1); }
public static void CreateThread(int ThreadCount)
{
Thread[] workerThread = new Thread[ThreadCount];
for (int i = 0; i < ThreadCount; i++)
{
workerThread[i] = new Thread(new ThreadStart(ConnectDBAndExecuteQueryWithLock));
workerThread[i].Name = i.ToString();
workerThread[i].Start();
}
}
public static void ConnectDBAndExecuteQueryWithLock()
{
lock (threadLock)
{
try
{
string sqlQuery = "insert into tblMasterLookup Values (" + Thread.CurrentThread.Name + ",'Test','2.0','Myapplication',GetDate())";
string connectionString = string.Format("Server={0}; Database = {1}; User Id = {2}; Password = {3};",
"serverNname",
"Databasename",
"ReadOnlyUser",
"ReadOnly12");
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
connection.Open();
}
catch(Exception e)
{ Console.WriteLine(e.StackTrace); }
using (SqlCommand command = new SqlCommand(sqlQuery, connection))
{
command.CommandTimeout = 80;
command.ExecuteNonQuery();
Console.WriteLine("Executed Thread.. " + Thread.CurrentThread.Name);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
Here is exception message

Sqlitedatabase + unity

i'm trying to connect my unity in sqlite database but i have an error. what does the error means ?
IndexOutOfRangeException: Array index is out of range.
Mono.Data.Sqlite.SqliteDataReader.GetSQLiteType (Int32 i)
Mono.Data.Sqlite.SqliteDataReader.VerifyType (Int32 i, DbType typ)
Mono.Data.Sqlite.SqliteDataReader.GetString (Int32 i)
callOneUser.GetOneUsername () (at Assets/callOneUser.cs:41)
callOneUser.Start () (at Assets/callOneUser.cs:22)
i'm trying to use this code. this is my void Start()
void Start()
{
Connection = "URI=file:" + Application.dataPath + "/English_Booster_Game_DB.s3db"; //Path to database.
GetOneUsername();
}
this is the GetOneUsername() process.
public void GetOneUsername()
{
using (IDbConnection dbConnection = new SqliteConnection(Connection))
{
dbConnection.Open();
using (IDbCommand dbCmd = dbConnection.CreateCommand())
{
string selectoneusername = "select UserData_name from user_data where UserData_status = 1";
dbCmd.CommandText = selectoneusername;
using (IDataReader reader = dbCmd.ExecuteReader())
{
while (reader.Read())
{
name.text = reader.GetString(1);
}
dbConnection.Close();
reader.Close();
}
}
}
}
In your query string, you get one column UserData_name.
string selectoneusername = "select UserData_name from user_data where UserData_status = 1";
It only returns you a column and index in C# start from "Zero". So you should change this line of your script:
name.text = reader.GetString(1);
to:
name.text = reader.GetString(0);
I hope it helps you

SQL Server Reporting Services - Report Expressions Execution

Say I have the following expression:
=DateAdd(DateInterval.Year,-1,Today())
Is there a SQL Server web service endpoint that'll allow me to pass in an expression and return the result of the executed expression? I looked through the endpoints listed here but couldn't find one.
Or is there another way to evaluate this expression?
I've found another way to evaluate the expression using VB.net (This assumes that #Wolfgang Kais is correct about VB.net use instead of VBA)
Here is the code snippet:
using System;
using System.CodeDom.Compiler;
using System.Text;
using Microsoft.VisualBasic;
namespace VbStringCompiler
{
internal class Program
{
public static void Main(string[] args)
{
new Program();
}
private const string CRLF = "\r\n";
private Program()
{
var vbCodeProvider = new VBCodeProvider();
var compilerParameters = new CompilerParameters();
compilerParameters.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
compilerParameters.ReferencedAssemblies.Add("System.dll");
compilerParameters.CompilerOptions = "/t:library";
compilerParameters.GenerateInMemory = true;
var stringBuilder = new StringBuilder();
stringBuilder.Append("Imports Microsoft.VisualBasic" + CRLF);
stringBuilder.Append("Imports System" + CRLF + CRLF);
stringBuilder.Append("Namespace Evaluate" + CRLF);
stringBuilder.Append("Class RunTime" + CRLF);
stringBuilder.Append("Public Function Run() As Object" + CRLF);
// insert code to return
stringBuilder.Append("Return DateAdd(DateInterval.Year, -1, Today())" + CRLF);
stringBuilder.Append("End Function" + CRLF);
stringBuilder.Append("End Class" + CRLF);
stringBuilder.Append("End Namespace" + CRLF);
try
{
var compilerResults =
vbCodeProvider.CompileAssemblyFromSource(compilerParameters, stringBuilder.ToString());
if (compilerResults.Errors.Count > 0)
{
foreach (CompilerError compilerError in compilerResults.Errors)
{
Console.Error.WriteLine(compilerError.ToString());
}
return;
}
var instance = compilerResults.CompiledAssembly.CreateInstance("Evaluate.RunTime");
var methodInfo = instance.GetType().GetMethod("Run");
var methodReturn = methodInfo.Invoke(instance, null);
Console.WriteLine(methodReturn);
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
}
}

Eclipse Luna : Tool to Create new MySQL database

I already know how to create new databases using MySQL command line .
Is there a tool provided by Eclipse Luna for creating MySQL databases ?
Thanks in advance .
Why would you need a tool, when it's this simple to create a database and tables with a Java application?
package database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class CreateDatabase implements Runnable {
private Connection connection;
private Statement statement;
private String databaseAddress;
private String logon;
private String password;
public CreateDatabase(String logon, String password) {
this.logon = logon;
this.password = password;
this.databaseAddress = "localhost:3306";
}
#Override
public void run() {
try {
connect();
createDatabase();
// dropTable("user_account");
createUserAccountTable();
commit();
disconnect();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void connect() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://"
+ databaseAddress + "/?" + "user=" + logon + "&password="
+ password);
statement = connection.createStatement();
}
private void createDatabase() throws SQLException {
String sql = "create database if not exists accounts";
statement.execute(sql);
displayUpdateCount(sql);
sql = "use accounts";
statement.execute(sql);
displayUpdateCount(sql);
sql = "set names 'utf8'";
statement.execute(sql);
displayUpdateCount(sql);
}
private void createUserAccountTable() throws SQLException {
String sql = "create table if not exists user_account ( " +
"user_account_number integer not null auto_increment, " +
"user_account_name varchar(40) not null, " +
"created_timestamp timestamp not null default current_timestamp, " +
"last_used_timestamp timestamp not null, " +
"primary key (user_account_number)) " +
"engine=InnoDB, " +
"character set=utf8, " +
"auto_increment=10000000 ";
statement.execute(sql);
displayUpdateCount(sql);
}
void dropTable(String tableName) throws SQLException {
String sql = "drop table if exists " + tableName;
statement.execute(sql);
displayUpdateCount(sql);
}
private void commit() throws SQLException {
String sql = "commit";
statement.execute(sql);
displayUpdateCount(sql);
}
private void displayUpdateCount(String sql) throws SQLException {
int count = statement.getUpdateCount();
StringBuilder builder = new StringBuilder();
builder.append("Executing SQL \"");
if (sql.length() > 40) builder.append(sql.substring(0, 40));
else builder.append(sql);
builder.append("\" resulted in ");
builder.append(count);
builder.append(" row");
if (count != 1) builder.append("s");
builder.append(" changed");
System.out.println(builder.toString());
}
private void disconnect() throws SQLException {
statement.close();
connection.close();
}
public static void main(String[] args) {
if (args.length != 2) {
String s = "The logon and password for the database " +
"must be provided.";
System.err.println(s);
} else {
new CreateDatabase(args[0], args[1]).run();
}
}
}

Resources