ssis script task throws error when run from sql agent job - sql-server

When I run this package from Visual Studio, it works fine, but when I run it from the sql agent job (SQL Server 2012 sp1) it throws error on the Script Task . I am running it under a proxy account in the sql agent job.
Error: Source: Set FS File Parameters Script Task Description: Exception has been thrown by the target of an invocation.
The proxy account is configured for the following subsystems:
ActiveX Script
SQL Server Analysis Services Command
SQL Server Analysis Services Query
SQL Server Analysis Services Package
PowerShell
I guess it is a problem with the proxy account using System.IO, because all other packages that do not access the file system are running fine, even though they have script tasks. All file path variables have been set up with UNC paths. The folder and files have everyone full control configuration.
How do I set it up to run from the sql agent job?
How do I check to make sure proxy account has access to file system?
Here is the code in the script task:
#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
#endregion
public void Main()
{
Dts.Variables["User::AS_FileArchivePath"].Value = "";
Dts.Variables["User::ExcludeProvidersArchivePath"].Value = "";
Dts.Variables["User::AS_FilePath"].Value = "";
Dts.Variables["User::ExcludeProvidersFilePath"].Value = "";
Dts.Variables["User::FeeScheduleFileName"].Value = "";
Dts.Variables["User::FileArchivePath"].Value = "";
//get load file name
String dirPath = Dts.Variables["User::FileDropFolder"].Value.ToString();
String fileExt = Dts.Variables["User::LoadFileExt"].Value.ToString();
String FileArchivePath = Dts.Variables["User::FileArchiveFolder"].Value.ToString() + Dts.Variables["User::FileArchiveDateFolder"].Value.ToString();
String FileName = "";
String FileType = "";
int FileSize = 0;
DirectoryInfo dir = new DirectoryInfo(dirPath);
foreach (FileInfo file in dir.GetFiles())
{
if (file.Extension.Contains(fileExt)
&& file.Name.StartsWith("DoNotDeleteTemplate") == false
&& file.Name.Contains("Products") == true
&& file.Name.Contains("Special") == false
&& file.Name.Contains("Exclude") == false)
{
FileName = file.Name;
FileSize = (int)file.Length;
FileType = file.Extension;
}
}
if (FileName != "")
{
Dts.Variables["User::FeeScheduleFileName"].Value = FileName;
Dts.Variables["User::FeeScheduleFileSize"].Value = FileSize;
Dts.Variables["User::FeeScheduleFileType"].Value = FileType;
//create archive folder
bool folderExists = Directory.Exists(FileArchivePath);
if (!folderExists)
Directory.CreateDirectory(FileArchivePath);
//set full archive path
Dts.Variables["User::FileArchivePath"].Value = FileArchivePath + "\\" + FileName;
//set full load file path
String filePath = Dts.Variables["User::FileDropFolder"].Value.ToString() + FileName;
}
Dts.TaskResult = (int)ScriptResults.Success;
}

Related

Create Database in PervasiveSQL from Command Line

How do I create a database in PervasiveSQL using the command line.
I know how to do it via Control Center, but I would rather create it via the command line. I am working to automate the standup of a PervasiveSQL box for a project I am working on. I have the server install happening silently and I am adjusting the Server Configuration using a RegKey import.
Now i just need to script the creation of the database. The new database will use existing database files which are already copied to the server.
In the documentation I am using found here: there is a utility called dbMaint (page 264) which seems like it would do the job, but I do not seem to have that tool on my server.
Thank you in advance for your help.
dbMaint is only provided for PSQL on Linux. There is a way to write a utility using the Distributed Tuning Interface (DTI) or Distributed Tuning Object (DTO) to create the database. I can't link to the PSQL documentation but there is a PSQL_DTI_GUIDE.pdf and PSQL_DTO_Guide.pdf in the PSQL v11 documentation download that describes how to use those APIs.
Found a C# sample I put together a while back. The Pervasive DTO library will need to be added as a reference. It's a COM object. The simple sample is:
using System;
using DTOLib;
namespace dtoTest
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
string compName = null;
string userName = null;
string password = null;
string dbname = null;
string ddflocation = null;
string datalocation = null;
dtoDbFlags dbflags = DTOLib.dtoDbFlags.dtoDbFlagDefault;
DTOLib.dtoResult result;
if (args.LongLength < 1)
{
Console.WriteLine("Invalid options.\n");
Console.WriteLine("Usage: dtoDBN.EXE <computername> <username> <password> <dbname> <ddf location> <data location> <DBFlage>");
Console.WriteLine("NOTE: locations must be relative to the computer where the PSQL engine is running.");
Console.WriteLine("DB Flags must be passed as integer in this example with these values: ");
Console.WriteLine(" P_DBFLAG_BOUND = 1; (* bound database - must have P_DBFLAG_CREATE_DDF too *)");
Console.WriteLine(" P_DBFLAG_RI = 2; (*relational integrity *)");
Console.WriteLine(" P_DBFLAG_CREATE_DDF = 4; (*create ddf flag *)");
Console.WriteLine(" P_DBFLAG_NA = 2147483648; (*not applicable *)");
Console.WriteLine(" P_DBFLAG_DEFAULT = (P_DBFLAG_BOUND or P_DBFLAG_RI); ");
return;
}
if (args.LongLength == 7)
{
compName = args[0].ToString();
userName = args[1].ToString();
password = args[2].ToString();
dbname = args[3].ToString();
ddflocation = args[4].ToString();
datalocation = args[5].ToString();
dbflags = (dtoDbFlags)Convert.ToInt32(args[6]);
}
Console.WriteLine("Create Pervasive Database using DTO and C#");
DtoSession mDtoSession = new DTOLib.DtoSession();
try
{
result = mDtoSession.Connect(compName, userName, password);
if (result != 0)
{
Console.WriteLine("Error connecting to server. Error code:");
}
else
{
//Create a Database name here.
DtoDatabase db = new DtoDatabase();
db.Name = dbname;
db.DdfPath = ddflocation;
db.DataPath = datalocation;
db.Flags = dbflags;
result = mDtoSession.Databases.Add(db);
if (result !=0)
{
Console.WriteLine(string.Format("Error creating the datbase ({0}). Error code: {1}", dbname, result.ToString()));
}
else
{
Console.WriteLine(string.Format("Database ({0}) created. ", dbname));
}
result = mDtoSession.Disconnect();
Console.ReadLine();
}
}
catch (Exception e1)
{
Console.WriteLine(e1.Message.ToString());
}
}
}
}

SQL Server DAC FX SchemaComparison SchemaCompareDatabaseEndpoint fails with no IntegratedSecuirty

I am trying to find newly created tables in the target database on publishing. Using DAC Fx I am able to find the differences and delete the tables after moving the newly created table to another db.
I developed and tested the code with IntegratedSecurity. Started failing on machines with SQLServer logins.
The moment I toggle the IntegratedSecurity to true it works. Is it a bug?
private void Analyse()
{
try
{
var sourceDacpac = new SchemaCompareDacpacEndpoint(DacPacSrc);
var csb = new SqlConnectionStringBuilder(ConnectionString);
csb.IntegratedSecurity = false;
var targetDatabase =new SchemaCompareDatabaseEndpoint(csb.ToString());
var comparison = new SchemaComparison(sourceDacpac, targetDatabase);
comparison.Options.DropObjectsNotInSource = true;
var result = comparison.Compare();
if (result.GetErrors().Any())
{
throw new Exception("Compare failed " + result.GetErrors().FirstOrDefault().Message);
}
var delta = new List<string>();
if (result.Differences != null && result.Differences.Any())
{
var deltaTables = result.Differences.Where(x => x.Name == "Table" && x.UpdateAction == SchemaUpdateAction.Delete);
delta = deltaTables.Select(x => x.TargetObject.Name.ToString()).ToList();
}
FindingDeltaCompleted?.Invoke(this, new DeltaEventArgs(delta));
}
catch (Exception ex)
{
Logging.HandleException(ex);
}
}
Try setting Persist Security Info=True in the SQL Authentication connection string.
SSDT/DAC Fx saves connection strings in registry under HKEY_CURRENT_USER\SOFTWARE\Microsoft\SSDT\ConnectionStrings. When Persist Security Info=True is not set, it won't restore the password when loading the connection strings from registry.

Loading SSIS package and it's connection managers in a WPF application

I created an integration service project with three connection managers (which are defined in project level), now I have an SSIS package (.dtsx file) and I want to use it in my app.
So I use Microsoft.SqlServer.Dts namespace as below:
string pkgLocation;
Package pkg;
Microsoft.SqlServer.Dts.Runtime.Application app;
DTSExecResult pkgResults;
pkgLocation = #"D:\My Job\Tadbirgaran\Integration Services Project\MyPackage.dtsx";
app = new Microsoft.SqlServer.Dts.Runtime.Application();
pkg = app.LoadPackage(pkgLocation, null);
pkgResults = pkg.Execute();
but this code does not load project connection managers obviously, so is there any way that I can load connection manager files programmatically and add them to the package connection property? or should I define connections in my package in the integration service project?
You can use configurations to control the connection properties programmatically. Here is an example.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Tasks.BulkInsertTask;
namespace configuration_API
{
class Program
{
static void Main(string[] args)
{
// Create a package and set two properties.
Package pkg = new Package();
pkg.EnableConfigurations = true;
pkg.ExportConfigurationFile(#"C:\conf.xml");
// Create a variable object and add it to the
// package Variables collection.
Variable varPkg = pkg.Variables.Add("var", false, "", 100);
varPkg.Value = 1;
string packagePathToVariable = varPkg.GetPackagePath();
// Create a configuration object and add it to the
// package configuration collection.
Configuration config = pkg.Configurations.Add();
// Set properties on the configuration object.
config.ConfigurationString = "conf.xml";
config.Description = "My configuration description";
config.ConfigurationType = DTSConfigurationType.ConfigFile;
config.PackagePath = packagePathToVariable;
// Save the package and its configuration.
Application app = new Application();
app.SaveToXml(#"c:\pkg.xml", pkg, null);
// Reload the package.
Package p1 = app.LoadPackage(#"c:\pkg.xml", null);
// Review the configuration information.
Configurations configs_After = pkg.Configurations;
foreach(Configuration confAfter in configs_After)
{
Console.WriteLine("ConfigurationString is {0}", confAfter.ConfigurationString);
Console.WriteLine("ConfigurationType is {0}", confAfter.ConfigurationType);
Console.WriteLine("CreationName is {0}", confAfter.CreationName);
Console.WriteLine("Description is {0}", confAfter.Description);
Console.WriteLine("Assigned ID is {0}", confAfter.ID);
Console.WriteLine("Name is {0}", confAfter.Name);
}
}
}
}
I ended up loading the project instead of package and setting connections from project to package as below:
private void SSISLoadData()
{
Project ssisProject = null;
DTSExecResult pkgResults;
try
{
ssisProject = Project.OpenProject(#"D:\My Job\TDB\Integration Services Project\bin\Development\Integration Services Project.ispac");
Package pkg = ssisProject.PackageItems[0].LoadPackage(null);
for (int i = 0; i < ssisProject.ConnectionManagerItems.Count; i++)
pkg.Connections.Join(ssisProject.ConnectionManagerItems[i].ConnectionManager);
pkg.Connections[0].ConnectionString = dataFolderPath + "\\*.csv";
pkg.Connections[1].ConnectionString = string.Format("Data Source =.; Initial Catalog = TDB; Provider = SQLNCLI11.1; Integrated Security = SSPI; Initial File Name = {0};", dbPath);
pkg.Connections[2].ConnectionString = string.Format("Data Source =.; Initial Catalog = TDBRawData; Provider = SQLNCLI11.1; Integrated Security = SSPI; Initial File Name = {0}\\TDBRawData.mdf;", Environment.CurrentDirectory);
pkgResults = pkg.Execute();
MessageBox.Show(pkgResults.ToString());
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
if (ssisProject != null)
ssisProject.Dispose();
}
}
I don't know if there is a better solution for this problem, but it works.

TFS2015: Full File Path Stored in SQL Database

I'm looking to see if the SQL Database behind TFS2015 (or any version of TFS, in this case 2015 or 2010) stores the full file path for a file. There is information that we include in the Project folder (namely the version number) and while I realize there are better ways to track this information, we have a lot of legacy data that only has the version stored within this path. I want to pull the data into Crystal Reports to strip off the information and then use it.
You want to get a list of folders in TFS Source Control, instead of querying in database, we recommend to achieve it programmatically. The blog below and the sample code associated with it will do what you want:
http://blogs.microsoft.co.il/blogs/shair/archive/2009/02/26/tfs-api-part-16-mapping-source-control-using-versioncontrolserver.aspx
Also, check the code snippet in this case, which should help you:
ICommonStructureService structureService = (ICommonStructureService)Tfscollection.GetService(typeof(ICommonStructureService));
ProjectInfo[] projects = structureService.ListAllProjects();
//combo_projects.ItemsSource = projects;
////Create VersionControlServer object from TFS
//sourceControl = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
RecursionType recursion = RecursionType.OneLevel;
Item[] items = null;
string path = "$/" + projects[0].Name;//"$/TescoPOC/FetchStoryfromTFS";
ItemSet itemSet = versionControl.GetItems(path, recursion);
items = itemSet.Items;
//Dictionary<string, int> FolderListName = new Dictionary<string, int>();
List<string> FolderListName = new List<string>();
foreach (Item keyItem in items)
{
char[] charSeparators = new char[] { '/' };
//Using split to isolated the Project Name and the File Name
string[] ss = keyItem.ServerItem.Split(charSeparators, StringSplitOptions.None);
if (keyItem != items[0])
{
string filename = keyItem.ServerItem.Replace(path + "/", string.Empty);
if (filename != "BuildProcessTemplates")
{
FolderListName.Add(filename);
//if (FolderListName.ContainsKey(filename))
// FolderListName[filename] = FolderListName[filename] + 1;
//else
// FolderListName.Add(filename, 1);
}
}
}

Codeigniter 2.0.3 with SQL Server Active Record

I'm working on upgrading a Codeigniter app I have running on 1.7.2 to 2.0.3 but I'm not able to connect to SQL Server . Both versions are running on the same server running php 5.2.10 and connecting to the same SQL Server.
This is the error from CI 2.0.3
Unable to connect to your database server using the provided settings.
Filename: core/Loader.php
Line Number: 260
This is the connection string I'm using which of course works on 1.7.2
$db['reports']['hostname'] = "mysqlserver";
$db['reports']['username'] = "sqluser";
$db['reports']['password'] = "sqlpass";
$db['reports']['database'] = "SQLReportDB";
$db['reports']['dbdriver'] = "mssql";
$db['reports']['dbprefix'] = "";
$db['reports']['pconnect'] = TRUE;
$db['reports']['db_debug'] = TRUE;
$db['reports']['cache_on'] = FALSE;
$db['reports']['cachedir'] = "";
$db['reports']['port'] = 972;
In the controller I call the connection with this
$report_db = $this->load->database('reports', TRUE);
Below is the function in the loader file where it reports the failure.
Line 260 is return DB($params, $active_record);
/**
* Database Loader
*
* #param string the DB credentials
* #param bool whether to return the DB object
* #param bool whether to enable active record (this allows us to override the config setting)
* #return object
*/
public function database($params = '', $return = FALSE, $active_record = NULL)
{
// Grab the super object
$CI =& get_instance();
// Do we even need to load the database class?
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db))
{
return FALSE;
}
require_once(BASEPATH.'database/DB.php');
if ($return === TRUE)
{
return DB($params, $active_record);
}
// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = '';
// Load the DB class
$CI->db =& DB($params, $active_record);
}
Here are some settings I use in connecting to a SQL Server you haven't listed. Might be required due to upgrade...
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$db['reports']['port'] is no longer valid
The port needs to be added to the end of the server
$db['reports']['hostname'] = "mysqlserver:972";

Resources