Modifiy column attribute using ADOX [ vc++ and MS Access] - ms-access

I have to add new columns in existing table. I can able to successfully add new column, but following exception occur while tying to modify the column attribute to nullable.
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done
Here my code,
HRESULT hr = S_OK;
ADOX::_CatalogPtr pCatalog = NULL;
ADOX::_TablePtr pTable = NULL;
ADOX::TablesPtr pTables = NULL;
hr = pCatalog.CreateInstance(__uuidof(Catalog));
pCatalog->PutActiveConnection("Provider='Microsoft.JET.OLEDB.4.0';data source='C:\\sample.mdb';");
pTables = pCatalog->GetTables();
pTable = pTables->Item["sampletable"];
hr = pTable->Columns->Append( "age", ADOX::adInteger, 0);
ASSERT(hr == S_OK);
pTable->Columns->Item["age"]->Attributes = ADOX::adColNullable;

The equivalent code in VBA works for me without error (assuming I have translated it faithfully).
Something perhaps to try is to create a Column object, set its properties including NULLable then append it to the Table object's Columns collection e.g. this in VBA:
Set oColumn = New ADOX.Column
oColumn.Name = "age"
oColumn.Type = ADOX.adInteger
oColumn.Attributes = ADOX.adColNullable
oTable.Columns.Append oColumn

Related

How do I check whether all the rows for a column are NULL in SSIS?

I'm working on a SSIS package where I have a text file with 5 columns. I need to check if all the rows for 5th column are NULL values.
If all the rows in 5th column are NULL then all the data should go for invalid file table.
If any row in 5th column have non NULL value then all the data should go to valid table.
You will need to read the entire file before being able to make the decision of where to write it to, so introduce a third table where you can stage the data first
Next part would be to build the logic that checks the staging table for all NULLS. Below query would return 0 if all was NULL and more than 0 if any record had a value
SELECT COUNT(*) FROM dbo.StagingTable ST WHERE ST.Column5 IS NOT NULL
Once you feed the answer into a variable you can use precedence constraints to fire the dataflow copy [staging to active] if the result was more than 0 or [staging to faulty] if the result was 0
personally if i had to perform this task I would use a script task to do it all:
Load into a data table
Use linq to check column to determine destination .Where(x => x[4]!=null).Count()
Load to destination via bulk Copy
You can check if the file is empty with C# using an OleDbDataAdapter and search the file, then determine where to load the file using SSIS Precedence Constraints. This example uses a CSV file without column names. If the columns do have names add the replacement code noted in the comments below. You will also need the using statements listed.
Add an SSIS Boolean variable. This is IsColumnNull in the following example. Next add a C# Script Task with IsColumnNull variable in the ReadWriteVariables field, and (optionally) a variable holding the file path ReadOnlyVariables pane.
Next set Precedence Constraints to check for both a true condition (has null rows) or false condition (does not have null records). Since the IsColumnNull variable is a Boolean, use just the variable itself as the expression to check for all null rows, but add ! for non-nulls, i.e. !#[User::IsColumnNull].
Connect the appropriate Data Flow Tasks with each destination table to the corresponding Precedence Constraint. For example, add the Data Flow Task with the "invalid file table" as the destination after the Precedence Constraint checking for a true value in the IsColumnNull variable.
Precedence Constraint For Rows with Nulls:
Precedence Constraint for Rows without Nulls:
Script Task Example:
using System;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Linq;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
string fullFilePath = Dts.Variables["User::FilePath"].Value.ToString();
string fileName = Path.GetFileName(fullFilePath);
string filePath = Path.GetDirectoryName(fullFilePath);
string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath
+ ";Extended Properties=\"text;HDR=No;FMT=Delimited\";";
//add filter for NOT NULL on given column to only return non-nulls
string sql = "SELECT F2 FROM " + fileName + " WHERE F2 IS NOT NULL";
//if file has column names replce "connStr" and "sql" as shown below
/*
string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath
+ ";Extended Properties=\"text;HDR=Yes;FMT=Delimited\";";
string sql = "SELECT ID FROM " + fileName + " WHERE ID IS NOT NULL";
*/
using (OleDbDataAdapter oleAdpt = new OleDbDataAdapter(sql, connStr))
{
DataTable dt = new DataTable();
oleAdpt.Fill(dt);
//if emtpy set IsColumnNull SSIS variable to true
if (dt.Select().Count() < 1)
{
Dts.Variables["User::IsColumnNull"].Value = true;
}
else
{
Dts.Variables["User::IsColumnNull"].Value = false;
}
}

Microsoft Jet OLEDB syntax error on UPDATE

I have a database similar to the one below:
Table1(AutoNumber, Text, Number, Memo) // this is field types
Table1(ID, Title, Price, Image)
I'm trying to update an existing element of the database in C# using:
const string connectionString = "provider=Microsoft.Jet.OLEDB.4.0;" + "data source=bd.mdb";
OleDbConnection m_dataBase = new OleDbConnection(connectionString);
OleDbConnection m_dataBase.Open();
SQL = "UPDATE Table1 SET Title='test', Price=35, Image='Test' WHERE ID=1";
OleDbCommand SQLQueryCommand = new OleDbCommand(SQL, m_dataBase);
int response = SQLQueryCommand.ExecuteNonQuery();
As a result I am getting this error. "Microsoft JET Database Engine Error syntax in UPDATE instruction".
What am I doing wrong?
PS: I can successfully do SELECT or INSERT, but not UPDATE.
Well, if your SQL command is the only problem, there are some visible issues.
Simply try to parametrize your Update clause using such as below which will prevent lots of little mistakes and also an SQL injection.
SQL = "UPDATE Table1 SET Title=?, Price=?, Image=? WHERE ID=?";
SQLQueryCommand.Parameter.Add("#MyTitle", OleDbType.VarChar).Value = "Test";
SQLQueryCommand.Parameter.Add("#MyPrice", OleDbType.Integer).Value = 35;
SQLQueryCommand.Parameter.Add("#MyImage", OleDbType.VarChar).Value = "TestAgain";
SQLQueryCommand.Parameter.Add("#MyID", OleDbType.VarChar).Value = 1;
To learn more about parametrization try having a look at the example in the bottom of this MSDN article.
OleDbCommand.Parameters Property
Also, it's a good practice to surround your connection inside a using statement.
using (var m_dataBase = new OleDbConnection(connectionString) { ... }

Receiving warning messages with EZAPI EzDerivedColumn and input columns

I am working with EZApi to assist in creating a package to stage data for transformation. It is working in terms of data movement. When opening the package in the designer however there are warning messages surrounding the Derived Column and the InputColumns being set to read only.
Warning 148 Validation warning. Staging TableName:
{AA700319-FC05-4F06-A877-599E826EA833}: The "Additional
Columns.Inputs[Derived Column Input].Columns[DataSourceID]" on
"Additional Columns" has usage type READONLY, but is not referenced by
an expression. Remove the column from the list of available input
columns, or reference it in an expression. StageFull.dtsx 0 0
I can manually change them in the designer to be Read/Write or unselect them and the warning goes away. I am unable to get this to work programmatically however.
I have tried removing the columns from the metadata which works but doesn't remove them from the component so the columns are still created in the xml.
XML section
<externalMetadataColumn refId="Package\Full\Staging TableName\DestinationStaging TableName.Inputs[OLE DB Destination Input].ExternalColumns[DataSourceID]" dataType="i4" name="DataSourceID" />
When I try to go to the underlying object and delete the column using component.DeleteInput(id) I get an error message stating that the input column cannot be removed.
0xC0208010
-1071611888
DTS_E_CANTDELETEINPUT
An input cannot be deleted from the inputs collection.
Here is the code I am using to create a data flow task with an OLEDB Source, Derived Column, and OLE DB Destination.
Note that the input columns are not present until after the derived column is attached to the Source: dc.AttachTo(source);
public class EzMyDataFlow : EzDataFlow
{
public EzMyDataFlow(EzContainer parent, EzSqlOleDbCM sourceconnection,
EzSqlOleDbCM destinationconnection, string destinationtable, string sourcecomannd, string dataflowname)
: base(parent)
{
Name = dataflowname;
EzOleDbSource source = new EzOleDbSource(this);
source.Connection = sourceconnection;
source.SqlCommand = sourcecomannd;
source.AccessMode = AccessMode.AM_SQLCOMMAND;
source.Name = string.Format("Source_{0}", dataflowname);
EzDerivedColumn dc = new EzDerivedColumn(this);
dc.Name = "Additional Columns";
// Setup DataSourceID
string columnName = DBSchema.ReportFoundationalColumns.DataSourceID;
dc.InsertOutputColumn(columnName);
dc.SetOutputColumnDataTypeProperties(columnName, DataType.DT_I4, 0, 0, 0, 0);
var c = dc.OutputCol(columnName);
var property = c.CustomPropertyCollection["Expression"];
property.Name = "Expression";
property.Value = "#[TM::SourceDatabaseID]";
property = c.CustomPropertyCollection["FriendlyExpression"];
property.Name = "FriendlyExpression";
property.Value = "#[TM::SourceDatabaseID]";
dc.AttachTo(source);
EzOleDbDestination destination = new EzOleDbDestination(this);
destination.Table = destinationtable;
destination.Connection = destinationconnection;
destination.Name = string.Format("Destination{0}", dataflowname);
destination.AttachTo(dc);
}
}

Why Could Linq to Sql Submit Changes Fail for Updates Despite Data in Change Set

I'm updating a set of objects, but the update fails on a SqlException that says "Incorrect Syntax near 'Where'".
So I crack open SqlProfiler, and here is the generated SQL:
exec sp_executesql N'UPDATE [dbo].[Addresses]
SET
WHERE ([AddressID] = #p0) AND ([StreetAddress] = #p1) AND ([StreetAddress2] = #p2) AND ([City] = #p3) AND ([State] = #p4) AND ([ZipCode] = #p5) AND ([CoordinateID] = #p6) AND ([CoordinateSourceID] IS NULL) AND ([CreatedDate] = #p7) AND ([Country] = #p8) AND (NOT ([IsDeleted] = 1)) AND (NOT ([IsNonSACOGZip] = 1))',N'#p0 uniqueidentifier,#p1 varchar(15),#p2 varchar(8000),#p3 varchar(10),#p4 varchar(2),#p5 varchar(5),#p6 uniqueidentifier,#p7 datetime,#p8 varchar(2)',#p0='92550F32-D921-4B71-9622-6F1EC6123FB1',#p1='125 Main Street',#p2='',#p3='Sacramento',#p4='CA',#p5='95864',#p6='725E7939-AEE3-4EF9-A033-7507579B69DF',#p7='2010-06-15 14:07:51.0100000',#p8='US'
Sure enough, no set statement.
I also called context.GetChangeSet() and the proper values are in the updates section.
Also, I checked the .dbml file and all of the properties Update Check values are 'Always'.
I am completely baffled on this one, any help out there?
I had overriden GetHashCode to return a concatenation of a few of the fields. When I changed it to return solely the hash of the primary key, it worked.
The root cause is that the updates will fail for an object whose hash code changes during its lifecycle, so when you override GetHashCode you need to pick attributes that cannot be updated, like the primary key,

Update Exist Data Using DataRow C#

I need to update my exist data in mysql database.
I write like this code;
String _id = lbID.Text;
dsrm_usersTableAdapters.rm_usersTableAdapter _t = new dsrm_usersTableAdapters.rm_usersTableAdapter();
dsrm_users _mds = new dsrm_users();
_mds.EnforceConstraints = false;
dsrm_users.rm_usersDataTable _m = _mds.rm_users;
_t.FillBy4(_m, _id);
if(_m.Rows.Count >0 )
{
DataRow _row = _m.Rows[0];
_row.BeginEdit();
_row["username"] = txtUserName.Text;
_row.EndEdit();
_row.AcceptChanges();
_t.Update(_m);
}
But nothing change my exists data. What is the Problem?
I think the problem is that you call DataRow.AcceptChanges() before calling DbDataAdapter.Update(). AcceptChanges will set the status of the datarow to "orignal" (or "not changed" - I don't remeber now). Try to move the call to AcceptChanges to after the Update.
Update requires a valid UpdateCommand when passed DataRow collection with modified rows
Yes I move the AccesptChange() after update bu now its give this error
Update requires a valid UpdateCommand when passed DataRow collection with modified rows
But now problem is, I use MySQL and I can not Wrie UpdateCommand , VS2008 does not accept the SQL command. Automaticly delete all SQL command. I dont understand the problem. So do you now another way without using SQL command (UpdateCommand) ?