As the code shown below, I want to get value from the OracleParameter object. Its datatype is datetime.
...
Dim cmd As New OracleCommand("stored_proc_name", cnObject)
cmd.Parameters.Add("tran_date_out", OracleDbType.Date, ParameterDirection.Output)
...
cmd.ExecuteNonQuery()
...
Dim tranDate As Date
tranDate = cmd.Parameters("tran_date_out").Value
When I assign value to tranDate variable, I get an error. But if I code as below, I get only the date.
tranDate = CDate(cmd.Parameters("tran_date_out").Value.ToString)
So how can I get the value both date and time to tranDate variable?
off the top of my head, the OracleParameter.Value, when an out parameter, is assigned to a strange Oracle boxed type. It seems like a completely terrible design or Oracle's part... but instead of returning String, you will get OracleString, etc.
Each of the Oracle types has a .Value that has the system type, but of course they don't all implement a common interface to expose this, so what I did was basically write a method to unbox the types:
/// <summary>
/// The need for this method is highly annoying.
/// When Oracle sets its output parameters, the OracleParameter.Value property
/// is set to an internal Oracle type, not its equivelant System type.
/// For example, strings are returned as OracleString, DBNull is returned
/// as OracleNull, blobs are returned as OracleBinary, etc...
/// So these Oracle types need unboxed back to their normal system types.
/// </summary>
/// <param name="oracleType">Oracle type to unbox.</param>
/// <returns></returns>
internal static object UnBoxOracleType(object oracleType)
{
if (oracleType == null)
return null;
Type T = oracleType.GetType();
if (T == typeof(OracleString))
{
if (((OracleString)oracleType).IsNull)
return null;
return ((OracleString)oracleType).Value;
}
else if (T == typeof(OracleDecimal))
{
if (((OracleDecimal)oracleType).IsNull)
return null;
return ((OracleDecimal)oracleType).Value;
}
else if (T == typeof(OracleBinary))
{
if (((OracleBinary)oracleType).IsNull)
return null;
return ((OracleBinary)oracleType).Value;
}
else if (T == typeof(OracleBlob))
{
if (((OracleBlob)oracleType).IsNull)
return null;
return ((OracleBlob)oracleType).Value;
}
else if (T == typeof(OracleDate))
{
if (((OracleDate)oracleType).IsNull)
return null;
return ((OracleDate)oracleType).Value;
}
else if (T == typeof(OracleTimeStamp))
{
if (((OracleTimeStamp)oracleType).IsNull)
return null;
return ((OracleTimeStamp)oracleType).Value;
}
else // not sure how to handle these.
return oracleType;
}
This probably isn't the cleanest solution, but... it was quick and dirty,a nd does work for me.
Just pass the OracleParameter.Value into this method.
Actually, I might have only 1/2 read your question before answering. I think Oracle's Date type only contains the date not the time.
The oracle type Timestamp has both the date and time.
Hope that helps! :)
I have not tested heavily, but here is a less verbose version of CodingWithSpike's answer using reflection...
public static object UnBoxOracleType(object oracleType) {
if(oracleType==null) {
return null;
}
if((bool)oracleType.GetType().GetProperty("IsNull").GetValue(oracleType)) {
return null;
}
return oracleType.GetType().GetProperty("Value").GetValue(oracleType);
}
Again you are passing OracleParameter.Value into this method.
Or for a more typesafe version you could do this:
public static object GetValue(OracleParameter param) {
if(param == null || param.Value==null) {
return null;
}
var oracleType=param.Value;
if((bool)oracleType.GetType().GetProperty("IsNull").GetValue(oracleType)) {
return null;
}
return oracleType.GetType().GetProperty("Value").GetValue(oracleType);
}
In this case you would pass the oracle parameter itself in to get the value back. This could also be implemented as an extension method if you so desired...
Related
BoldReports ReportViewer Controller:
I'm using the ReportHelper.GetParametersWithValues() function in the OnReportLoaded() method to retrieve the report parameters. It is successfully retrieving the list of parameters, however, only the name attributes are populated - the values are null.
private ReportParameterInfoCollection _rptParamColl;
public void OnReportLoaded(ReportViewerOptions reportOption)
{
_rptParamColl = ReportHelper.GetParametersWithValues(jsonArray, this, _cache);
if (_rptParamColl != null)
{
foreach (ReportParameterInfo rptParam in _rptParamColl)
{
if (rptParam.Name == "OrgID")
{
if (rptParam.Values != null )
{
// perform appropriate validation on rptParam.Values[0]
}
}
}
}
}
In the code sample above, rptParam.Name has a value, but the rptParam.Values is null. I know the values exist, as when I inspect the jsonArray object, they are in there (although oddly, after calling ReportHelper.GetParametersWithValues(), the jsonArray object is cleared? Same also happens when calling ReportHelper.GetDataSources(). This is also a problem, as I want to call both methods, and after calling one, cannot call the other... )
Any ideas what I may be doing wrong?
Using the PostReportAction method you can get the client-side parameter value. Please refer to the below code snippet,
public object PostReportAction([FromBody] Dictionary<string, object> jsonResult)
{
if (jsonResult.ContainsKey("parameters") && jsonResult["parameters"] != null)
{
var parameterValues = Newtonsoft.Json.JsonConvert.DeserializeObject<BoldReports.Web.ReportParameterInfoCollection>(jsonResult["parameters"].ToString());
}
return ReportHelper.ProcessReport(jsonResult, this, this._cache);
}
I'm using EPPlus as a calculations server. Here is my code:
using (var xlp = new ExcelPackage(stream))
{
OfficeOpenXml.ExcelWorksheet Sheet = xlp.Workbook.Worksheets["sheet1"];
//Some code for feeding user data to excel sheet
//...
//We first invoke calculate method to let contraints of data validation get updated.
xlp.Workbook.Calculate();
var v = Sheet.DataValidations["A1"];
if (v != null)
{
switch (v.ValidationType.Type)
{
case OfficeOpenXml.DataValidation.eDataValidationType.DateTime:
OfficeOpenXml.DataValidation.ExcelDataValidationDateTime V1 = (OfficeOpenXml.DataValidation.ExcelDataValidationDateTime)v;
try
{
//this line doesn't do any thing
V1.Validate();
}
catch
{
}
break;
case ...
}
}
}
I had read somewhere that Validate() method throws exception for invalid data. It doesn't.
My question: How to use the Validate() method?
That would depend on what the content of the cell and the settings of the validator's Operator:
http://epplus.codeplex.com/SourceControl/latest#EPPlus/DataValidation/ExcelDataValidationOperator.cs
/// <summary>
/// Operator for comparison between Formula and Formula2 in a validation.
/// </summary>
public enum ExcelDataValidationOperator
{
any,
equal,
notEqual,
lessThan,
lessThanOrEqual,
greaterThan,
greaterThanOrEqual,
between,
notBetween
}
The ExcelDataValidationDateTime (eventually) derives from ExcelDataValidationWithFormula<IExcelDataValidationFormulaDateTime> which contains the implemenation of Validate():
http://epplus.codeplex.com/SourceControl/latest#EPPlus/DataValidation/ExcelDataValidationWithFormula.cs
public override void Validate()
{
base.Validate();
if (Operator == ExcelDataValidationOperator.between || Operator == ExcelDataValidationOperator.notBetween)
{
if (string.IsNullOrEmpty(Formula2Internal))
{
throw new InvalidOperationException("Validation of " + Address.Address + " failed: Formula2 must be set if operator is 'between' or 'notBetween'");
}
}
}
So it will throw an exception (invalidate) when the validation operation is either ExcelDataValidationOperator.between or ExcelDataValidationOperator.notBetween and Forumla2 is not set (not to be confused with the primary Formula). In other words, it considers the validator invalid when you are using an operation which requires TWO values/formulas to compare but only one is set.
I have a use-case in which i need to take in the date of a month to return the previous month's last date.
Ex: input:20150331 output:20150228
I will be using this previous month's last date to filter a daily partition(in pig script).
B = filter A by daily_partition == GetPrevMonth(20150331);
I have created an UDF(GetPrevMonth) which takes the date and returns the previous month's last date.But unable to use it on the filter.
ERROR:Could not infer the matching function for GetPrevMonth as multiple or none of them fit. Please use an explicit cast.
My udf takes tuple as input.
Googling it says that UDF cannot be applied on filters.
Is there any workaround? or am i going wrong somewhere?
UDF:public class GetPrevMonth extends EvalFunc<Integer> {
public Integer exec(Tuple input) throws IOException {
String getdate = (String) input.get(0);
if (getdate != null){
try{
//LOGIC to return prev month date
}
Need help.Thanks in advance.
You can call a UDF in a FILTER, but you are passing a number to the function while you expect it to receive a String (chararray inside Pig):
String getdate = (String) input.get(0);
The simple solution would be to cast it to chararray when calling the UDF:
B = filter A by daily_partition == GetPrevMonth((chararray)20150331);
Generally, when you see some error like Could not infer the matching function for X as multiple or none of them fit, 99% of the time the reason is that the values you are trying to pass to the UDF are wrong.
One last thing, even if it is not necessary, in a future you might want to write a pure FILTER UDF. In that case, instead of inheriting from EvalFunc, you need to inherit from FilterFunc and return a Boolean value:
public class IsPrevMonth extends FilterFunc {
#Override
public Boolean exec(Tuple input) throws IOException {
try {
String getdate = (String) input.get(0);
if (getdate != null){
//LOGIC to retrieve prevMonthDate
if (getdate.equals(prevMonthDate)) {
return true;
} else {
return false;
}
} else {
return false;
}
} catch (ExecException ee) {
throw ee;
}
}
}
I'm using IPreUpdateEventListener for audit purposes. My solution is exactly as Ayende Rahien says here. Something like this:
public bool OnPreUpdate(PreUpdateEvent #event)
{
var audit = #event.Entity as IHaveAuditInformation;
if (audit == null)
return false;
var time = DateTime.Now;
var name = WindowsIdentity.GetCurrent().Name;
Set(#event.Persister, #event.State, "UpdatedAt", time);
Set(#event.Persister, #event.State, "UpdatedBy", name);
audit.UpdatedAt = time;
audit.UpdatedBy = name;
return false;
}
My problems is I must set audit.UpdatedAt = time; to have the value in my entity, but it makes the object dirty and causes another more update to database. I need both the new value in my object but don't want duplicate update. Is there any way?
This should not cause two updates; something else is going on. The problem may be that the database UpdatedAt field resolution is different then the .NET DateTime.Now resolution. My code is nearly identical to yours but I use this method to create the timestamp:
/// <summary>
/// Return a DateTime with millisecond resolution to be used as the timestamp. This is needed so that DateTime of an existing instance
/// will equal one that has been persisted and returned from the database. Without this, the times differ due to different resolutions.
/// </summary>
/// <returns></returns>
private static DateTime GetTime()
{
var now = DateTime.Now;
var ts = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond, DateTimeKind.Local);
return ts;
}
I read this question: Command Line Parser for .NET.
I thought that was what I was looking for, but the library Command Line Parser Library is not Compact framework friendly...
I REALLY don't want to write a CL parser and I have been drifting away from the real purpose of my little app because of this unfortunate trial.
Does someone know of a library that fits the compact-framework? (preferably with simplicity and functionality like the one mentioned above)
Does not matter whether version 2 or 3.5
I developed this framework, maybe it helps:
The SysCommand is a powerful cross-platform framework, to develop Console Applications in .NET. Is simple, type-safe, and with great influences of the MVC pattern.
https://github.com/juniorgasparotto/SysCommand
namespace Example.Initialization.Simple
{
using SysCommand.ConsoleApp;
public class Program
{
public static int Main(string[] args)
{
return App.RunApplication();
}
}
// Classes inheriting from `Command` will be automatically found by the system
// and its public properties and methods will be available for use.
public class MyCommand : Command
{
public void Main(string arg1, int? arg2 = null)
{
if (arg1 != null)
this.App.Console.Write(string.Format("Main arg1='{0}'", arg1));
if (arg2 != null)
this.App.Console.Write(string.Format("Main arg2='{0}'", arg2));
}
public void MyAction(bool a)
{
this.App.Console.Write(string.Format("MyAction a='{0}'", a));
}
}
}
Tests:
// auto-generate help
$ my-app.exe help
// method "Main" typed
$ my-app.exe --arg1 value --arg2 1000
// or without "--arg2"
$ my-app.exe --arg1 value
// actions support
$ my-app.exe my-action -a
This is what I'm using. I borrowed it from somewhere, but not sure where:
using System.Collections.Specialized;
using System.Text.RegularExpressions;
/// <summary>
/// Parses the command line arguments into a name/value collection
/// </summary>
public class CommandLineArgumentParser
{
#region Fields
private StringDictionary parameters;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CommandLineArgumentParser"/> class.
/// </summary>
/// <param name="args">command-line arguments
/// </param>
public CommandLineArgumentParser(string[] args)
{
this.parameters = new StringDictionary();
Regex spliter = new Regex(#"^-{1,2}|^/|=|:", RegexOptions.IgnoreCase | RegexOptions.Compiled);
Regex remover = new Regex(#"^['""]?(.*?)['""]?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
string parameter = null;
string[] parts;
// Valid parameters forms:
// {-,/,--}param{ ,=,:}((",')value(",'))
// Examples:
// -param1 value1 --param2 /param3:"Test-:-work"
// /param4=happy -param5 '--=nice=--'
foreach (string txt in args)
{
// Look for new parameters (-,/ or --) and a
// possible enclosed value (=,:)
parts = spliter.Split(txt, 3);
switch (parts.Length)
{
// Found a value (for the last parameter
// found (space separator))
case 1:
if (parameter != null)
{
if (!this.parameters.ContainsKey(parameter))
{
parts[0] = remover.Replace(parts[0], "$1");
this.parameters.Add(parameter, parts[0]);
}
parameter = null;
}
// else Error: no parameter waiting for a value (skipped)
break;
// Found just a parameter
case 2:
// The last parameter is still waiting.
// With no value, set it to true.
if (parameter != null)
{
if (!this.parameters.ContainsKey(parameter))
{
this.parameters.Add(parameter, "true");
}
}
parameter = parts[1];
break;
// Parameter with enclosed value
case 3:
// The last parameter is still waiting.
// With no value, set it to true.
if (parameter != null)
{
if (!this.parameters.ContainsKey(parameter))
{
this.parameters.Add(parameter, "true");
}
}
parameter = parts[1];
// Remove possible enclosing characters (",')
if (!this.parameters.ContainsKey(parameter))
{
parts[2] = remover.Replace(parts[2], "$1");
this.parameters.Add(parameter, parts[2]);
}
parameter = null;
break;
}
}
// In case a parameter is still waiting
if (parameter != null)
{
if (!this.parameters.ContainsKey(parameter))
{
this.parameters.Add(parameter, "true");
}
}
}
#endregion
#region Properties
/// <summary>
/// Gets a count of command line arguments
/// </summary>
public int Count
{
get
{
return this.parameters.Count;
}
}
/// <summary>
/// Gets the value with the given parameter name
/// </summary>
/// <param name="param">name of the parameter</param>
/// <returns>the value of the parameter</returns>
public string this[string param]
{
get
{
return this.parameters[param];
}
}
#endregion
}
http://commandline.codeplex.com/ I've used this so many times I've lost count. Maybe it works for CE. If not, it'll provide a fantastic starting point.