writing to file using Script task in SSIS 2005 not working - ssis

could anybody give me any clue why this script not doing the job to write the file?
in fact when i'm trying to run it on SSIS 2005, the task showed up green and success
I'm confused
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.IO
Public Class ScriptMain
Public Sub Main()
System.IO.File.AppendAllText("e:\test.txt","<![CDATA[ <b>Sales</b>]]>")
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
Thank you in advance

Looks like there is a problem passing in the XML. Try the following and see if that works, if so, then the XML fragment you are adding is the issue.
Public Sub Main()
Dim strFile As String
Dim strText As String
strFile = "e:\test.txt"
strText = "test"
Try
File.AppendAllText(strFile, strText)
Catch e As Exception
Dts.TaskResult = Dts.Results.Failure
End Try
Dts.TaskResult = Dts.Results.Success
End Sub

Related

How to use GetStringAsync in VB.NET

I don't really know what I'm going. Trying to gather small pieces of code from the web
I ended up with this:
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json.Linq
Module Module1
Sub Main()
LoadData()
End Sub
Private Async Sub LoadData()
Dim client As New Net.Http.HttpClient()
Dim url = "my url which return json"
Dim uri As New Uri(url)
Dim json As String = Await client.GetStringAsync(uri)
Dim j = JObject.Parse(json)("TIME SERIES INTRADAY")
Dim openPrice = j("1. open").Value(Of Double)
Diagnostics.Debug.WriteLine(openPrice)
Console.ReadLine()
End Sub
End Module
There is no issue when I build but when I run, I get this erroer message when I step on row
Dim json As String = Await client.GetStringAsync(uri)
error code:
The program '[4032] AVT.exe' has exited with code 0 (0x0).
Do you know why this line is returning this error?
Framework 4.5
You won't be able to do top-level Await in a console program. You can still make it work (preserving the Async on LoadData) with the following changes:
Change the signature of LoadData to Private Async Function LoadData() As Task
Change the call in Main to `LoadData.GetAwaiter().GetResult()
This will block in Main which is fine because there is no message loop to support a non-blocking wait. This is only appropriate in a console program, if you were doing this in any other setting your original implementation would have been correct (except that you should always use Async Function ... As Task in preference to Async Sub in any context aside from event handlers).
Yes, you can do this even in a console application.
I suggest you to use an ApplicationContext in order to keep all alive.
Doing as you shows, so, calling your LoadData()
your Main Sub going tasks are:
Enter
(and immediately after)
Exit
.
Take a look on code below to figure out the mechanism that you need to do what you want to do.
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json.Linq
Module Module1
Public Class MyApplicationContext
Inherits ApplicationContext
Private Async Sub LoadData()
Dim client As New Net.Http.HttpClient()
Dim url = "https://stackoverflow.com/questions/59324373/how-to-use-getstringasync-in-vb-net"
Dim uri As New Uri(url)
Dim json As String = Await client.GetStringAsync(uri)
Console.WriteLine(json)
Diagnostics.Debug.WriteLine(json)
'Dim j = JObject.Parse(json)("TIME SERIES INTRADAY")
'Dim openPrice = j("1. open").Value(Of Double)
'Diagnostics.Debug.WriteLine(openPrice)
Console.ReadLine() 'Here is stopped/waiting for user
'Here your application can be stopped after her work
'Application.Exit()
End Sub
Public Sub New()
MyBase.New()
AddHandler Application.ApplicationExit, AddressOf OnApplicationExit
LoadData()
End Sub
Private Sub OnApplicationExit(ByVal sender As Object, ByVal e As EventArgs)
Try
' delete your data here
Catch
End Try
End Sub
End Class
Public Sub Main()
Dim context As MyApplicationContext = New MyApplicationContext()
Application.Run(context)
End Sub
End Module

"InvalidOperationException : Connection must be valid and open" On MySqlConnection

I was working on a VB.Net project (first time, I was previously working in VBA) and I seem to have trouble establishing connecion with a MariaDB/MySQL database.
I wanted to get all rows for one column to use it as source for a ComboBox named CBClient in a Form
Here my codes so far:
First class: ClassSQL
Imports MySql.Data.MySqlClient
Imports MySql.Data.Types
Public Class ClassSQL
Public Shared ConfigSQL As String =
"DATABASE=(My actual DB);DATA SOURCE=(IP of the server);USER ID=(UserID);PASSWORD=(Password)"
Public Shared ConnectDB As New MySqlConnection(ConfigSQL)
End Class
And the Form class:
Imports MySql.Data.MySqlClient
Public Class NewDossier
Private Sub NewDossier_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GetCBClient()
End Sub
Sub GetCBClient()
ClassSQL.ConnectDB.Open()
Dim Requete As String = "SELECT NomClient FROM MSClients"
Dim Query As New MySqlCommand(Requete, ClassSQL.ConnectDB)
Dim rs As MySqlDataReader = Query.ExecuteReader
Do While rs.Read
CBClient.Items.Add(rs.GetString("NomClient"))
Loop
ClassSQL.ConnectDB.Close()
End Sub
End Class
On ClassSQL.ConnectDB.Open() in the Form class I have the exception:
InvalidOperationException : Connection must be valid and open
Is my connection wrong somehow? Or is it something I did wrong?
Is there a way to specify the port?
In ADO.Net, it is not generally a good idea to try to re-use the same connection object throughout an application, because of a feature called Connection Pooling. The connector is already managing this for you. Instead, it really is better to just create a new connection instance for most queries. Just keep the connection string handy and re-use that. This works especially well in conjunction with the IDisposable/Using pattern.
Additionally, it's a good idea to put your queries in the same Class or Module as your connection string, isolated from the rest of the application, where each query is a function that returns the data and (usually) accepts an argument telling it what data to find.
Public Module SQL
'Making this private helps ensure you remember to put database activities here in this class.
Private ConnectionString As String = "DATABASE=(My actual DB);DATA SOURCE=(IP of the server);USER ID=(UserID);PASSWORD=(Password)"
'You could also design this function to return a DataTable object, if Iterator blocks aren't your thing
Public Iterator Function GetMSClients() As IEnumerable(Of String)
Dim Requete As String = "SELECT NomClient FROM MSClients"
Using cn As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(Requete, cn)
cn.Open()
Using rdr As MySqlDataReader = cmd.ExecuteReader()
While rdr.Read()
Yield rdr.GetString("NomClient")
End While
End Using
End Using
End Function
End Module
Public Class NewDossier
Private Sub NewDossier_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CBClient.Items.AddRange(SQL.GetMSClients().ToArray())
End Sub
End Class

How to convert my MySQL Connection to a Class in VB.NET 2010?

I have multiple forms, each form performs specific task that requires connection to the MySQL Server.
On each form, these are declared:
Imports MySql.Data.SqlClient
Dim myConnObj As New MySqlConnection
And I use them like this:
myConnObj = New MySqlConnection()
myConnObj.ConnectionString = "Server=" & db_Server & ";Database=" & dbase & ";UID= & "db_UserID & ";PWD=" & db_Password
myConnObj.Open()
''Things to do here
myConnObj.Close
I would like to convert this process into a Class to minimize the code and it should be available thru all the forms, but I dont know where to start.
Though I've already created an empty Class in VB named clsConnect.vb
Please note that "dbase" (the database I will connect into) should be varying.
Thanks in advance.
Well, you go take the singleton approach:
VB.NET:
Public Class DBase
#Region "Singleton"
Private Shared instances As New Dictionary(Of [String], DBase)()
Public Shared Function GetInstance(dbname As [String]) As DBase
If Not instances.ContainsKey(dbname) Then
instances(dbname) = New DBase(dbname)
End If
Return instances(dbname)
End Function
#End Region
Private connection As MySqlConnection
Private Sub New(dbase As [String])
Me.connection = New MySqlConnection()
Me.connection.ConnectionString = "...connection string implementing dbase..."
Me.connection.Open()
End Sub
Protected Overrides Sub Finalize()
Try
Me.connection.Close()
Finally
MyBase.Finalize()
End Try
End Sub
#Region "Database Methods"
' add the various method calls to the database here.
#End Region
End Class
'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: #telerik, #toddanglin
'Facebook: facebook.com/telerik
'=======================================================
C#
public class DBase
{
#region Singleton
private static Dictionary<String, DBase> instances = new Dictionary<String, DBase>();
public static DBase GetInstance(String dbname)
{
if (!instances.ContainsKey(dbname))
{
instances[dbname] = new DBase(dbname);
}
return instances[dbname];
}
#endregion
private MySqlConnection connection;
private DBase(String dbase)
{
this.connection = new MySqlConnection();
this.connection.ConnectionString = "...connection string implementing dbase...";
this.connection.Open();
}
~DBase()
{
this.connection.Close();
}
#region Database Methods
// add the various method calls to the database here.
#endregion
}
Then you can access it from where ever, and make calls to it:
VB.NET
Dim db As DBase = DBase.GetInstance("DEMO")
Dim name As [String] = db.GetUsernameFromEmail("jsmith#contoso.com")
C#
DBase db = DBase.GetInstance("DEMO");
String name = db.GetUsernameFromEmail("jsmith#contoso.com");
Very crude, but gets the job done. You could get more elaborate with validating, connection checking, cleanup and (possibly) thread-safing, but I'll keep the example short and sweet.

Get schema name for dependent objects with SMO

Using a source script component in SSIS, I am attempting to retreive details of all objects which depend on a table. So far, I have the object type and name but can't retreive the schema. Does anyone know how to acheive this in SMO?
My script component code is:
' Microsoft SQL Server Integration Services user script component
' This is your new script component in Microsoft Visual Basic .NET
' ScriptMain is the entrypoint class for script components
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Common
Public Class ScriptMain
Inherits UserComponent
Public Overrides Sub CreateNewOutputRows()
'
'
'
Dim TargetSQLServer As Server
Dim TargetDatabase As Database
Dim TargetTable As Table
Dim uc As New UrnCollection()
Dim dw As New DependencyWalker
Dim dt As DependencyTree
Dim dc As DependencyCollection
Dim dcn As DependencyCollectionNode
Dim sp As New Scripter
Dim outputString As String
TargetSQLServer = New Server("localhost")
TargetDatabase = TargetSQLServer.Databases("AdventureWorks")
For Each TargetTable In TargetDatabase.Tables
' Exclude these objects
If TargetTable.IsSystemObject = False Then
uc = New UrnCollection()
uc.Add(TargetTable.Urn)
sp = New Scripter
sp.Server = TargetSQLServer
' Get dependencies
dw = New DependencyWalker
dw.Server = TargetSQLServer
dt = dw.DiscoverDependencies(uc, DependencyType.Children)
sp = New Scripter(TargetSQLServer)
dc = New DependencyCollection
dc = sp.WalkDependencies(dt)
outputString = ""
For Each dcn In dc
Me.Output0Buffer.AddRow()
Me.Output0Buffer.Database = TargetDatabase.Name.ToString
Me.Output0Buffer.Table = TargetTable.Name.ToString
outputString = dcn.Urn.ToString
Me.Output0Buffer.Dependency.AddBlobData(Text.Encoding.GetEncoding(1252).GetBytes(outputString))
Me.Output0Buffer.ObjectType = dcn.Urn.Type.ToString
outputString = dcn.Urn.GetNameForType(dcn.Urn.Type.ToString).ToString
Me.Output0Buffer.ObjectName.AddBlobData(Text.Encoding.GetEncoding(1252).GetBytes(outputString))
outputString = ""
Me.Output0Buffer.Schema.AddBlobData(Text.Encoding.GetEncoding(1252).GetBytes(outputString))
Next
End If
Next
End Sub
End Class
Hey ekoner,
I have working code that walks the dependency tree in databases, and resolved the issue with simple string parsing.
Your urn will be returned is in the form of
///StoredProcedure[#Name='uspUpdateEmployeeHireInfo' and #Schema='HumanResources']
Just parse for #Name and then for #Schema.
Download the source code for DBSourceTools : http://dbsourcetools.codeplex.com
Have a look at DBSourceToolsLib.SysObjects.UrnParser
And also DBSourceToolsLib.SysObjects.SODependencyTree for working examples.

SSIS - How to access a RecordSet variable inside a Script Task

How do you access a RecordSet variable inside a Script Task?
Listed below is the code I used to load a datatable in a C# script task from a recordset or resultset variable. "User::transactionalRepDBs" is a SSIS variable of Object (System.Object) that was loaded through a "Full result set" from a execute SQL task script. This link assisted me.
using System.Data.OleDb;
DataTable dt= new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.Fill(dt, Dts.Variables["User::transactionalRepDBs"].Value);
foreach (DataRow row in dt.Rows)
{
//insert what you want to do here
}
On the script tab, make sure you put the variable in either the readonlyvariables or readwritevariables text boxes.
Here is a simple script that I use to format the errors in a data flow (saved in a RecordSet Variable) into the body of an email. Basically I read the recordset varialbe into a datatable and process it row by row with the for loops. After this task completes I examine the value of uvErrorEmailNeeded to determine if there is anything to email using a conditional process flow connector. You will also need to add a reference to system.xml in your vb script. This is in SQL 2005.
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Xml
Imports System.Data.OleDb
Public Class ScriptMain
Public Sub Main()
Dim oleDA As New OleDbDataAdapter
Dim dt As New DataTable
Dim col As DataColumn
Dim row As DataRow
Dim sMsg As String
Dim sHeader As String
oleDA.Fill(dt, Dts.Variables("uvErrorTable").Value)
If dt.Rows.Count > 0 Then
Dts.Variables("uvErrorEmailNeeded").Value = True
For Each col In dt.Columns
sHeader = sHeader & col.ColumnName & vbTab
Next
sHeader = sHeader & vbCrLf
For Each row In dt.Rows
For Each col In dt.Columns
sMsg = sMsg & row(col.Ordinal).ToString & vbTab
Next
sMsg = sMsg & vbCrLf
Next
Dts.Variables("uvMessageBody").Value = "Error task. Error list follows:" & vbCrLf & sHeader & sMsg & vbCrLf & vbCrLf
End If
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
An easier way I found (using C#) is simply casting the object as a string array. This is how my C# code looks now:
public void Main()
{
string[] arreglo = (string[])Dts.Variables["User::arreglo"].Value;
...
foreach (string elemento in arreglo)
{
// do stuff on each element of the array/collection
}
...
}