Code:
string sqlCommand = #"UPDATE table SET active = 0 WHERE id IN (#CommaSeparatedId)";
string sqlParamName = "CommaSeparatedId";
string sqlParamValue = "111, 222";
try
{
using (NpgsqlConnection connection = new NpgsqlConnection())
{
// Get connection string from Web.config
connection.ConnectionString = _connectionString;
connection.Open();
Int32 rowsAffected;
using (NpgsqlCommand command = new NpgsqlCommand(sqlCommand, connection))
{
NpgsqlParameter sqlParam = new NpgsqlParameter(sqlParamName, NpgsqlTypes.NpgsqlDbType.Varchar);
// Code below no exception occur, and active not updated to 0
// sqlParam.Value = sqlParamValue;
// This code works for only one value
sqlParam.Value = "111";
command.Parameters.Add(sqlParam);
rowsAffected = command.ExecuteNonQuery();
}
}
}
catch (NpgsqlException pgEx)
{
throw pgEx;
}
The problem is:
If I'm using the 111, 222 as the sqlParam.Value'rowsAffected = 0, but if I'm using only111or222rowsAffected = 1`. That means it success to updated when only 1 value but will failed if trying to update more than 1 value.
Expected Query:
UPDATE table
SET active = 0
WHERE id IN ('111', '222');
What I'm missing in code above?
The problem you are facing is due to the fact that the parameter value "111,222" will be seen by the database engine not like two distinct values, but as one.
The database search for a record with ID = "111,222" and find nothing matching the request.
You should try to use a stored procedure and execute a Dynamic SQL according to the syntax required by PostgreSQL
Related
I am trying to export dynamic list items to excel using ClosedXML. The goal is to allow end user to select the columns to be exported. Since the columns are dynamic, I use.ToDynamicListAsync() of System.Linq.Dynamic.Core name space.
The problem is excel export works fine if I create anonymous object but throws error when I directly pass the select query as shown below. I directly pass the select cols bcoz the cols will be known only at runtime.
Below is the code snapshot for clarity
using ClosedXML.Excel;
using System.Linq.Dynamic.Core;
var filter = "MeetingNo = 85";
var query = context.PrmProjects.AsNoTracking().Where(filter);
var items = await query.Select(x => new
{
x.OrganizationId,
x.ProjectNo,
x.MeetingNo,
x.Name
}).ToDynamicListAsync();
using var wb = new XLWorkbook();
var ws = wb.Worksheets.Add();
ws.Cell(3, 1).InsertData(items); /// WORKS FINE
var selectQuery = $"new(OrganizationId,ProjectNo,MeetingNo,Name)";
var items1 = await query.Select(selectQuery).ToDynamicListAsync();
using var wb2 = new XLWorkbook();
var ws2 = wb2.Worksheets.Add();
ws2.Cell(3, 1).InsertData(items1); /// THROW ERROR 'Parameter count mismatch'
`
In the above sample code InsertData with the list 'items' works fine but 'items1' throws an error 'Parameter count mismatch'
Screenshot of List 'items', working fine:
Screenshot of List 'items1', throw error:
Error screenshot:
Can any one please help me. What am I doing wrong.
The cause for this error is that System.Linq.Dynamic.Core creates a new dynamic type based on DynamicClass which does also have an indexer:
public object? this[string name]
{
get
{
//
}
set
{
//
}
}
The ClosedXml calls GetProperties(...) in the ObjectReader.cs class and this GetProperties does return 5 entries:
OrganizationId
ProjectNo
MeetingNo
Name
Index --> This is the indexer defined on the DynamicClass which is not really a normal property.
So actually ClosedXML should be fixed to exclude indexer methods.
Example:
int parameters = propertyInfo.GetIndexParameters().Length;
if (parameters > 0)
{
// The property is an indexer, skip this.
continue;
}
I have an existing object called unsettled:
var unsettled =
{
processor: 1,
dayFrom: 10,
dayTo: 12
}
Im trying to add an object called pName as I do with Angular, but it is not working.
unsettled.pname = "something"
It does work if unsettled.pname already exists on the object, but not if I want to create it.
Also, after a sql Query where I get several results, I need to create an array. Same thing, when I do
const pool = await utils.poolPromise
const recordset = await pool.request()
.query(sqlString)
if (recordset.rowsAffected[0] > 0) {
unsettled.processors = recordset.recordset;
}
Is not working either (the array processors is not being created).
Thanks.
For the array, try:
if (recordset.rowsAffected[0] > 0) {
unsettled["processors"] = recordset.recordset;
}
As for as pName, please try
unsettled["pname"] = "something"
Has a transaction function that worked in first pass and at 2nd pass, got "TypeError: Cannot set _id to Null value. Both passes were to create a new transaction. Besides, system seemed to indicate that there was value for variable that was being used to assign to_id. In this case,
print"this.selectedLeave_id" and saw value as expected. However, Angular right away in next statement complaining that Null value was set to "this.SLTran.leave_id".
Below pls find code and any help is appreciated.
onSubmitLeaveTran()
{
if (this.selectedLeaveTran_id != 0) // means first loaded all trans and then select from table to modify
{
this.sLTran = this.tempSLTran; // tempSLTran was from row selected to be modified
this.sLTran.leaveType = this.tempLeaveType; // from dialog box edited data
this.sLTran.leaveStartDate = this.tempLeaveStartDate; // from dialog box edited data
this.sLTran.leaveEndDate = this.tempLeaveEndDate; // from dialog box edited data
this.sLTran.numDaysRequested = this.tempNumDaysRequested; // from dialog box edited data
console.log('2-2.5 inside onSubmit Leave Tran for update :',this.sLTran);
this.staffLeaveDataSvc.updateSLTran(this.sLTran).subscribe((sLTran:staffLeaveTran) => {this.sLTran = sLTran});
}
else
{ // a new tran
console.log('2-2.4 inside onSubmit Leave Tran selectedLeave_id for new tran:',this.selectedLeave_id);
this.sLTran.leave_id = this.selectedLeave_id; // first established the leave_id associated with this new tran
this.sLTran.leaveType = this.tempLeaveType;
this.sLTran.leaveStartDate = this.tempLeaveStartDate;
this.sLTran.leaveEndDate = this.tempLeaveEndDate;
this.sLTran.numDaysRequested = this.tempNumDaysRequested;
this.staffLeaveDataSvc.addSLTran(this.sLTran).subscribe(
(sLTran:staffLeaveTran) => {
this.sLTran = sLTran
});
}
};
Package is successfully generated. but derived column showing the error bellow-
Validation error. This is a programmed DataFlowTask Derived Column [2]: Attempt to parse the expression "Empid" failed and returned error code 0xC00470A2. The expression cannot be parsed. It might contain invalid elements or it might not be well-formed. There may also be an out-of-memory error. MyProgrammedDataflowTaskWithDerivedColumn.dtsx
bellow is my code-
// Create an application
Application app = new Application();
// Create a package
Package pkg = new Package();
//Setting some properties
pkg.Name = #"MyProgrammedDataflowTaskWithDerivedColumn";
//Adding a connection to the database AdventureWorksLT2008R2
ConnectionManager ConnMgrAdvent = pkg.Connections.Add("OLEDB");
ConnMgrAdvent.ConnectionString = "Data Source=412-1682;Initial Catalog=Empdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;";
ConnMgrAdvent.Name = #"AdventureWorks2008R2";
ConnMgrAdvent.Description = #"SSIS Connection Manager for OLEDB Source";
//Adding a connection to the database Import_DB
ConnectionManager ConnMgrImport_DB = pkg.Connections.Add("OLEDB");
ConnMgrImport_DB.ConnectionString = "Data Source=412-1682;Initial Catalog=stgEmpdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;";
ConnMgrImport_DB.Name = #"Import_DB";
ConnMgrImport_DB.Description = #"SSIS Connection Manager for OLEDB Source";
//Adding the dataflow task to the package
Executable exe = pkg.Executables.Add("STOCK:PipelineTask");
TaskHost TKHSQLHost = (TaskHost)exe;
TKHSQLHost.Name = "This is a programmed DataFlowTask";
MainPipe dataFlowTask = (MainPipe)TKHSQLHost.InnerObject;
// Create the source component.
IDTSComponentMetaData100 source =
dataFlowTask.ComponentMetaDataCollection.New();
source.ComponentClassID = "DTSAdapter.OleDbSource.3";
CManagedComponentWrapper srcDesignTime = source.Instantiate();
srcDesignTime.ProvideComponentProperties();
// Assign the connection manager.
if (source.RuntimeConnectionCollection.Count > 0)
{
source.RuntimeConnectionCollection[0].ConnectionManager =DtsConvert.GetExtendedInterface(ConnMgrAdvent);
source.RuntimeConnectionCollection[0].ConnectionManagerID =
pkg.Connections["AdventureWorks2008R2"].ID;
}
// Set the custom properties of the source.
srcDesignTime.SetComponentProperty("AccessMode", 0);
srcDesignTime.SetComponentProperty("OpenRowset", "[dbo].[emp1]");
// Connect to the data source, and then update the metadata for the source.
srcDesignTime.AcquireConnections(null);
srcDesignTime.ReinitializeMetaData();
srcDesignTime.ReleaseConnections();
// Create the destination component.
IDTSComponentMetaData100 destination =
dataFlowTask.ComponentMetaDataCollection.New();
destination.ComponentClassID = "DTSAdapter.OleDbDestination.3";
CManagedComponentWrapper destDesignTime = destination.Instantiate();
destDesignTime.ProvideComponentProperties();
// Assign the connection manager.
destination.RuntimeConnectionCollection[0].ConnectionManager =
DtsConvert.GetExtendedInterface(ConnMgrImport_DB);
if (destination.RuntimeConnectionCollection.Count > 0)
{
destination.RuntimeConnectionCollection[0].ConnectionManager =
DtsConvert.GetExtendedInterface(ConnMgrImport_DB);
destination.RuntimeConnectionCollection[0].ConnectionManagerID =
pkg.Connections["Import_DB"].ID;
}
// Set the custom properties of the destination
destDesignTime.SetComponentProperty("AccessMode", 0);
destDesignTime.SetComponentProperty("OpenRowset", "[dbo].[emp1]");
// Connect to the data source, and then update the metadata for the source.
destDesignTime.AcquireConnections(null);
destDesignTime.ReinitializeMetaData();
destDesignTime.ReleaseConnections();
//Derived Column
IDTSComponentMetaData100 derived =
dataFlowTask.ComponentMetaDataCollection.New();
derived.Name = "Derived Column Component";
derived.ComponentClassID = "DTSTransform.DerivedColumn.3";
CManagedComponentWrapper DesignDerivedColumns = derived.Instantiate();
DesignDerivedColumns.ProvideComponentProperties(); //design time
derived.InputCollection[0].ExternalMetadataColumnCollection.IsUsed = false;
derived.InputCollection[0].HasSideEffects = false;
//update the metadata for the derived columns
DesignDerivedColumns.AcquireConnections(null);
DesignDerivedColumns.ReinitializeMetaData();
DesignDerivedColumns.ReleaseConnections();
//Create the path from source to derived columns
IDTSPath100 SourceToDerivedPath = dataFlowTask.PathCollection.New();
SourceToDerivedPath.AttachPathAndPropagateNotifications(source.OutputCollection[0],derived.InputCollection[0]);
//Create the path from derived to desitination
IDTSPath100 DerivedToDestinationPath = dataFlowTask.PathCollection.New();
DerivedToDestinationPath.AttachPathAndPropagateNotifications(derived.OutputCollection[0], destination.InputCollection[0]);
// derivedColumns.SetUsageType(dInput.ID, vdInput, vColumn.LineageID, DTSUsageType.UT_READONLY);
//Give me an output column
IDTSInput100 dInput;
IDTSVirtualInput100 vdInput;
//Get this components default input and virtual input
dInput = derived.InputCollection[0];
vdInput = dInput.GetVirtualInput();
IDTSOutputColumn100 myCol = derived.OutputCollection[0].OutputColumnCollection.New();
myCol.Name = "RowKey";
myCol.SetDataTypeProperties(Microsoft.SqlServer.Dts.Runtime.Wrapper.DataType.DT_I4, 0, 0, 0, 0);
myCol.ExternalMetadataColumnID = 0;
myCol.ErrorRowDisposition = DTSRowDisposition.RD_FailComponent;
myCol.TruncationRowDisposition = DTSRowDisposition.RD_FailComponent;
IDTSCustomProperty100 myProp = myCol.CustomPropertyCollection.New();
myProp.Name = "Expression";
myProp.Value = "Empid";// + vColumn.LineageID;
myProp = myCol.CustomPropertyCollection.New();
myProp.Name = "FriendlyExpression";
myProp.Value = "Empid";
//Create the input columns for the transformation component
IDTSInput100 input = derived.InputCollection[0];
IDTSVirtualInput100 derivedInputVirtual = input.GetVirtualInput();
input.ErrorRowDisposition = DTSRowDisposition.RD_NotUsed;
input.ErrorOrTruncationOperation = "";
DesignDerivedColumns.ReleaseConnections();
// Get the destination's default input and virtual input.
IDTSInput100 destinationinput = destination.InputCollection[0];
int destinationInputID = input.ID;
IDTSVirtualInput100 vdestinationinput = destinationinput.GetVirtualInput();
//Iterate through the virtual input column collection.
foreach (IDTSVirtualInputColumn100 vColumn in vdestinationinput.VirtualInputColumnCollection)
{
IDTSInputColumn100 vCol = destDesignTime.SetUsageType(destinationinput.ID, vdestinationinput, vColumn.LineageID, DTSUsageType.UT_READWRITE);
destDesignTime.MapInputColumn(destinationinput.ID, vCol.ID, destinationinput.ExternalMetadataColumnCollection[vColumn.Name].ID);
}
app.SaveToXml(String.Format(#"D:\{0}.dtsx", pkg.Name), pkg, null);
solved this by adding bellow code to validate derived column component :-
IDTSInput100 DerivedColumnInput = derived.InputCollection[0];
IDTSVirtualInput100 DerivedColumnVirtualInput = DerivedColumnInput.GetVirtualInput();
IDTSVirtualInputColumnCollection100 DerivedColumnVirtualInputColumns = DerivedColumnVirtualInput.VirtualInputColumnCollection;
foreach (IDTSVirtualInputColumn100 virtualInputColumnDT in DerivedColumnVirtualInputColumns)
{
// Select column, and retain new input column
if (virtualInputColumnDT.Name=="Empid")
{
designDerivedColumns.SetUsageType(DerivedColumnInput.ID, DerivedColumnVirtualInput, virtualInputColumnDT.LineageID, DTSUsageType.UT_READONLY);
}
}
I am trying to retrieve CLOB data via ODP.NET.
My problem is that reader.GetValue(i).ToString() can return only up to 4000 characters and the rest of the data is truncated.
If I use reader.GetOracleClob(1).Value I got "Specified cast is not valid" error.
Any idea what I have missed? I am using ODP.NET 4.0
Below is my code.
using (OracleConnection oConn = new OracleConnection())
{
oConn.ConnectionString = pConnstr;
oConn.Open();
using (OracleCommand oCmd = new OracleCommand("select varchar_column, clob_column from test", oConn))
{
oCmd.InitialLOBFetchSize = -1;
string key, value, value1;
var rd = oCmd.ExecuteReader();
while (rd.Read())
{
if (rd.IsDBNull(1)) { value = ""; }
else
{
key = rd.GetValue(0).ToString();
value = rd.GetValue(1).ToString(); // unable to get more than 4000.
value1 = rd.GetOracleClob(1).Value; // Specified cast is not valid.
}
}
}
}
I found in Oracle Doc that When the InitialLOBFetchSize property is set to a nonzero value, the GetOracleBlob, GetOracleClob, GetOracleBlobForUpdate, and GetOracleClobForUpdate typed accessor methods are disabled. That may help explain why I got "Specified cast is not valid" error.
However, I still cannot get data beyond 4000 limit.
I have tried different combinations documented here
http://docs.oracle.com/cd/E11882_01/win.112/e18754/featData.htm#autoId6
But no luck.
Actually the code works correctly and gets the data it supposed to get. I just didn't realize that my data is incomplete and appeared to be a retrieval problem at the first look. Sorry.
The following is the good code.
using (OracleConnection oConn = new OracleConnection())
{
oConn.ConnectionString = pConnstr;
oConn.Open();
using (OracleCommand oCmd = new OracleCommand("select varchar_column, clob_column from test", oConn))
{
oCmd.InitialLOBFetchSize = -1;
string key, value;
var rd = oCmd.ExecuteReader();
while (rd.Read())
{
if (rd.IsDBNull(1)) { value = ""; }
else
{
key = rd.GetValue(0).ToString();
value = rd.GetValue(1).ToString();
}
}
}
}
The above solution did not work for me. It turns out my data was not CLOB or BLOB but LONG Data! So the fix is just to set:
oCmd.InitialLONGFetchSize= -1;
Instead of
oCmd.InitialLOBFetchSize = -1;
Please leave a comment if this method worked for you also.