OCI-21560 OCIObjectNew OCI_TYPECODE_TABLE - oracle11g
I am stuck with this problem for a while now. I went through tons of code / examples and docs on this (not much though).
What I am trying to do is: Reading and Writing a PL/SQL tables through Procedure IN/OUT parameters using OCI from C.
The Oracle package is defined as follows:
DROP PACKAGE pkg_test;
DROP TYPE ARRRECNR;
DROP TYPE ARRRECDATA;
CREATE OR REPLACE TYPE ARRRECNR IS TABLE OF NUMBER(8);
/
CREATE OR REPLACE TYPE ARRRECDATA IS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE PACKAGE pkg_test
IS
PROCEDURE test_proc1 (
p_RecordNr In ARRRECNR,
p_RecordData In ARRRECDATA,
p_RecCount OUT Number,
p_outrecorddata OUT ARRRECDATA
);
END;
/
CREATE OR REPLACE PACKAGE BODY pkg_test
IS
PROCEDURE test_proc1 (
p_RecordNr In ARRRECNR,
p_RecordData In ARRRECDATA,
p_RecCount OUT Number,
p_OutRecordData OUT ARRRECDATA
) IS
BEGIN
p_RecCount = 0;
p_OutRecordData := ARRRECDATA();
FOR I IN 1..p_RecordData.COUNT
LOOP
p_OutRecordData.extend();
p_OutRecordData(I) := p_RecordData(I) || ' ' || to_char(p_RecordNr(I));
p_RecCount := p_RecCount + I;
END LOOP;
END test_proc1;
END pkg_test;
/
And now I am trying to call the following PL/SQL:
BEGIN
pkg_test.test_proc1 (
P_RECORDNR => :P_RECORDNR,
P_RECORDDATA => :P_RECORDDATA,
P_RECCOUNT => :P_RECCOUNT,
P_OUTRECORDDATA => :P_OUTRECORDDATA
);
END
/
And Invocation the C(OCI) is as follows:
status = OCIStmtPrepare2(..., &stmthp,...
NULL /*const OraText *key*/,
0 /*ub4 keylen*/,
OCI_NTV_SYNTAX,
OCI_DEFAULT);
if (status != OCI_SUCCESS) { return -1; }
OCIBind *bindpp_P_RECCOUNT = NULL;
sword P_RECCOUNT = 0;
status = OCIBindByName(stmthp, &bindpp_P_RECCOUNT, errhp,
(text *)":P_RECCOUNT", strlen(":P_RECCOUNT"),
(ub1 *)&P_RECCOUNT, (sword)sizeof(P_RECCOUNT),
SQLT_INT, (dvoid *)0, (ub2 *)0, (ub2)0, (ub4)0, (ub4 *)0,
OCI_DEFAULT);
if (status != OCI_SUCCESS) { return -1; }
OCIBind *bindpp_P_RECORDNR = NULL;
status = OCIBindByName(stmthp, &bindpp_P_RECORDNR, errhp, (text *)":P_RECORDNR",
-1, NULL /*void *valuep*/,
(sb4)sizeof(OCITable *) /*sb4 value_sz*/,
SQLT_NTY /*ub2 dty*/,
NULL /*void *indp*/,
NULL /*ub2 *alenp*/,
NULL /*ub2 *rcodep*/,
0 /*ub4 maxarr_len*/,
NULL /*ub4 *curelep*/,
OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }
OCIBind *bindpp_P_RECORDDATA = NULL;
status = OCIBindByName(stmthp, &bindpp_P_RECORDDATA, errhp, ":P_RECORDDATA", (sb4)-1,
NULL /*void *valuep*/, (sb4)sizeof(OCITable *) /*sb4 value_sz*/,
SQLT_NTY /*ub2 dty*/, NULL /*void *indp*/, NULL /*ub2 *alenp*/,
NULL /*ub2 *rcodep*/, 0 /*ub4 maxarr_len*/, NULL /*ub4 *curelep*/,
OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }
OCIBind *bindpp_P_OUTRECORDDATA = NULL;
status = OCIBindByName(stmthp, &bindpp_P_OUTRECORDDATA, errhp, ":P_OUTRECORDDATA",(sb4)-1,
NULL /*void *valuep*/,(sb4)sizeof(OCITable *) /*sb4 value_sz*/,
SQLT_NTY /*ub2 dty*/,
NULL /*void *indp*/, NULL /*ub2 *alenp*/, NULL /*ub2 *rcodep*/,
0 /*ub4 maxarr_len*/, NULL /*ub4 *curelep*/, OCI_DEFAULT /*ub4 mode*/);
if (status != OCI_SUCCESS) { return -1; }
OCIType *ArrRecNr = NULL;
status = OCITypeByName(envhp, errhp, svchp, NULL, 0,
"ARRRECNR", (ub4)strlen("ARRRECNR"),
NULL, 0, OCI_DURATION_SESSION,
OCI_TYPEGET_ALL, &ArrRecNr);
if (status != OCI_SUCCESS || !ArrRecNr) { return -1; }
OCIType *ArrRecData = NULL;
status = OCITypeByName(envhp, errhp, svchp, NULL, 0,
"ARRRECDATA", (ub4)strlen("ARRRECDATA"),
NULL, 0, OCI_DURATION_SESSION,
OCI_TYPEGET_ALL, &ArrRecData);
if (status != OCI_SUCCESS || !ArrRecData) { return -1; }
OCITable *in_P_RECORDNR = NULL;
status = OCIObjectNew(envhp, errhp, svchp,
OCI_TYPECODE_TABLE, bindpp_P_RECORDNR,
NULL, OCI_DURATION_SESSION,
TRUE, &in_P_RECORDNR);
if (status != OCI_SUCCESS)
{
printf("\nOCIObjectNew(envhp %p, errhp %p, svchp %p,\n"
"OCI_TYPECODE_TABLE %d, bindpp_P_RECORDNR %p\n"
"NULL %p, OCI_DURATION_SESSION %d\n"
"TRUE %d, &in_P_RECORDNR %p)\n",
envhp, errhp, svchp,
OCI_TYPECODE_TABLE, bindpp_P_RECORDNR,
NULL, OCI_DURATION_SESSION,
TRUE, &in_P_RECORDNR);
return -1;
}
Full Code
Which is giving me the following error while trying to OCIBindByName:
OCI-21560: argument 4 is null, invalid, or out of range
Server
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
Client
instantclient_12_1
I checked all the input parameters and 4th isn't NULL:
OCIObjectNew(
envhp 0000027D223CE9B0,
errhp 0000027D223FC590,
svchp 0000027D223FB808,
OCI_TYPECODE_TABLE 248,
bindpp_P_RECORDNR 0000027D23D6B1B0,
NULL 0000000000000000,
OCI_DURATION_SESSION 10,
TRUE 1,
&in_P_RECORDNR 000000BCD47FFE00
)
What am I missing?
Related
Pagination on DevExtreme dxDataGrid with Skip / Take loadOptions
We have a table with a large amount of data and I do not want to load it at once for my dxDataGrid. I want to implement paging with Skip / Take which is supplied from the dxDataGrid's DataSourceLoadOptions. This is my controller: [HttpGet] public async Task<Object> GetSalesOrdersWithTotals(DataSourceLoadOptions loadOptions) { try { var results = await SalesOrderService.GetSalesOrdersWithTotals(loadOptions.Skip, loadOptions.Take, 40); loadOptions.Skip = 0; loadOptions.Take = 0; return DataSourceLoader.Load(results, loadOptions); } catch (Exception ex) { return Json(new { code = "422", success = false, message = "Unable to fetch sales orders with totals - " + ex.ToString() }); } } This is the service that returns the data: public async Task<IEnumerable<SalesOrderWithTotals>> GetSalesOrdersWithTotals(int skip, int take, int defaultPageSize) { if (take == 0) { //Fix for passing a 0 take take = defaultPageSize; } var salesOrderWithTotals = from o in _context.SalesOrder select new SalesOrderWithTotals { SalesOrderId = o.SalesOrderId, Net = _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum(), Tax = _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum() * (o.Tax.Percentage /100), Gross = _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum() + _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum() * (o.Tax.Percentage / 100), Name = o.Customer.Name, CustomerOrderNumber = o.CustomerOrderNumber, Contact = o.Contact, OrderDate = o.OrderDate }; return await salesOrderWithTotals.Skip(skip).Take(take).ToListAsync(); } Looking at SQL profiler, this takes the first 40 records but of course the dxDataGrid is not aware of the total count of records so pagination is not available. What would be the best method to achieve what I want in this case? Many thanks
You must do an extra query to get the count of your SalesOrder and keep it in for example salesOrderCount. Then keep the Load method return data as bellow. LoadResult result = DataSourceLoader.Load(results, loadOptions); LoadResult has a parameter called totalCount so set it with the real count of your data: result.totalCount = salesOrderCount; and then return result; Now the dxDataGrid is aware of the total count of records.
Financial Dimension after save is empty
I have financial dimension which contact values like BuildingID and ContractID. When new building is created, dimension is properly filled with data. But, after that there is need for contract creation. When contract is created there is value in financial dimension field for contractID. But, when contract is saved, financial dimension for contract id disappear. When I check in DIMENSIONATTRIBUTEVALUESET table value for that ContractID dimension is null, there is only value for BuildingID. I have this method for init dimensions: void initDimensions() { DimensionDefault dimension; PMGOrgDimension orgDimension; CompanyId companyId; PMEGround ground; PMEBuilding building; switch(pmcContract.EstateType) { case PMCEstateType::Ground : ground = PMEGround::find(pmcContract.EstateId); dimension = PMEObjectLegalEntity::find(ground.TableId, ground.RecId).DefaultDimension; orgDimension = ground.OrgDimension; companyId = ground.CompanyId; break; case PMCEstateType::Building : building = PMEBuilding::find(pmcContract.EstateId); dimension = PMEObjectLegalEntity::find(building.TableId, building.RecId).DefaultDimension; orgDimension = building.OrgDimension; companyId = building.CompanyId; break; default : dimension = pmcContract.DefaultDimension; orgDimension = pmcContract.OrgDimension; companyId = pmcContract.CompanyId; break; } pmcContract.DefaultDimension = dimension; pmcContract.OrgDimension = orgDimension; pmcContract.CompanyId = companyId; } Is there something what I missing ?
Try changing this line: pmcContract.DefaultDimension = dimension; To this: pmcContract.DefaultDimension = DimensionDefaultingService::serviceMergeDefaultDimensions(pmcContract.DefaultDimension, dimension);
Issue is in this method: static server public DimensionDefault tableDimension(Common _c, DimensionDefault _d) { DimensionAttribute dimensionAttribute; DimensionAttributeValue dimensionAttributeValue; DimensionAttributeSetItem dimensionAttributeSetItem; DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage; DimensionDefault cDimensionDefault; DimensionDefault ret; ; ret = _d; select firstonly RecId from dimensionAttribute where dimensionAttribute.BackingEntityTableId == _c.TableId join firstonly RecId from dimensionAttributeSetItem where dimensionAttributeSetItem.DimensionAttributeSet == DimensionCache::getDimensionAttributeSetForLedger() && dimensionAttributeSetItem.DimensionAttribute == dimensionAttribute.RecId; if (dimensionAttributeSetItem.RecId != 0) { dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimensionAttribute.RecId, _c.RecId, false, true); if (dimensionAttributeValue.RecId != 0) { dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage(); dimensionAttributeValueSetStorage.addItemValues(dimensionAttributeValue.DimensionAttribute, dimensionAttributeValue.RecId, dimensionAttributeValue.HashKey); cDimensionDefault = dimensionAttributeValueSetStorage.save(); if (cDimensionDefault != 0) { ret = LedgerDimensionDefaultFacade::serviceMergeDefaultDimensions(cDimensionDefault, _d); } } } return ret; } Merge is not working. It only takes values for _d. Not merging them.
Datatables Object Reference not set to instance of an object for one variable
This is my datatables serverside implementation. FilterInput contains 5 variables: Level <- string Message <- string Exception <-string StartDate <- DateTime EndDate <- DateTime For some reason when I run this code as it is, I will always get this error: {System.NullReferenceException: Object reference not set to an instance of an object. This is referring to this line: data = data.Where( u => u.Level.ToString().ToLower().Contains(FilterInput.Level.ToLower()) && u.Message.ToString().ToLower().Contains(FilterInput.Message.ToLower()) && u.Exception.ToString().ToLower().Contains(FilterInput.Exception.ToLower()) ).ToList(); However, if I remove the search for FilterInput.Exception, everything runs fine again. I have tested it with input ("abc") or without input ("") and the results are the same. The other FilterInputs don't have the same error. public JsonResult Search(SearchViewModels Input, EventLogsSearchViewModel FilterInput) { JsonResult result = new JsonResult(null); try { var data = dbContext.EventLogs.ToList(); int totalRecords = data.Count; var modelStructure = new Dictionary<int, string>(); modelStructure.Add(1, "Level"); modelStructure.Add(2, "TimeStamp"); modelStructure.Add(3, "LogEvent"); modelStructure.Add(4, "Message"); modelStructure.Add(5, "MessageTemplate"); modelStructure.Add(6, "Exception"); modelStructure.Add(7, "Properties"); var StartDate = FilterInput.StartDate != default(DateTime); var EndDate = FilterInput.EndDate != default(DateTime); if ((!string.IsNullOrEmpty(FilterInput.Level) && !string.IsNullOrWhiteSpace(FilterInput.Level)) || (!string.IsNullOrEmpty(FilterInput.Message) && !string.IsNullOrWhiteSpace(FilterInput.Message)) || (!string.IsNullOrEmpty(FilterInput.Exception) && !string.IsNullOrWhiteSpace(FilterInput.Exception)) || (StartDate && EndDate)) { data = data.Where( u => u.Level.ToString().ToLower().Contains(FilterInput.Level.ToLower()) && u.Message.ToString().ToLower().Contains(FilterInput.Message.ToLower()) && u.Exception.ToString().ToLower().Contains(FilterInput.Exception.ToLower()) ).ToList(); data = data.Where(u => u.TimeStamp >= FilterInput.StartDate && u.TimeStamp <= FilterInput.EndDate).ToList(); } if (!(string.IsNullOrEmpty(Input.Order) && string.IsNullOrEmpty(Input.OrderDir))) { var columnName = modelStructure.FirstOrDefault(f => f.Key == Convert.ToInt32(Input.Order)); data = data.AsQueryable().OrderBy(columnName.Value + " " + Input.OrderDir).ToList(); } int recFilter = data.Count; data = data.Skip(Input.StartRec).Take(Input.PageSize).ToList(); var modifiedData = data.Select(u => new EventLogsListViewModel { Id = u.Id, Message = u.Message, MessageTemplate = u.MessageTemplate, Level = u.Level, TimeStamp = u.TimeStamp, Exception = u.Exception, Properties = u.Properties, LogEvent = u.LogEvent }); result = this.Json(new { draw = Convert.ToInt32(Input.Draw), recordsTotal = totalRecords, recordsFiltered = recFilter, data = modifiedData, order = Input.Order, orderdir = Input.OrderDir }); } catch (Exception e) { logger.LogError(e, LoggingGlobals.LoadingException); } return result; } EDIT: The exception still happens even when FilterInput.Exception is not null
Case Statements in LINQ query - AnonymousType to String?
I basically have the following: public ActionResult Search(string searchString, string clientNo, int status = -1) { var statusLst = new List<string>(); var statusNoQry = from b in db.Briefs orderby b.Status select new { status = ( b.Status == 0 ? "Requested" : b.Status == 1 ? "In Progress" : "Undefined" ) }; statusLst.AddRange(statusNoQry.Distinct()); <<--- ERROR HERE ViewBag.status = new SelectList(statusLst); var ClientNoLst = new List<string>(); var ClientNoQry = from b in db.Briefs orderby b.Client_No_ where b.Client_Type == 0 select b.Client_No_; ClientNoLst.AddRange(ClientNoQry.Distinct()); ViewBag.clientNo = new SelectList(ClientNoLst); var briefs = from b in db.Briefs select b; Session["searchString"] = searchString; Session["clientNo"] = clientNo; if (!String.IsNullOrEmpty(searchString)) { briefs = briefs.Where(s => s.Client_No_.Contains(searchString) || s.Name.Contains(searchString)); } if ((status > -1) && (status < 10)) { briefs = briefs.Where(y => y.Status == status); } if (string.IsNullOrEmpty(clientNo)) return View(briefs); else return View(briefs.Where(x => x.Client_No_ == clientNo)); } However, I receive the following area: Error 7 Argument 1: cannot convert from 'System.Linq.IQueryable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<string>' Status is of type int but I would like to cast it to string for my dropdownlist. I'm quite new to all this, what is the appropriate way of achieving this?
Your selector is returning an anonymous type: select new { status = ( b.Status == 0 ? "Requested" : b.Status == 1 ? "In Progress" : "Undefined" ) }; You need to return a set of strings though. The error is telling you exactly what the problem is. select (b.Status == 0 ? "Requested" : b.Status == 1 ? "In Progress" : "Undefined"); Edit - You didn't post the rest of the method, but from you have your also not disposing your context object, which can cause problems. Normally you wrap this in a using clause.
AS 3 functions optional value getting error
I have a gui class, The functions optional value getting error. If i am not passing the fillcolor and other optional values. Error: ReferenceError: Error #1069: Property fillColor not found on String and there is no default value. AS 3.0 var windowBase:Sprite = UIClip("Sprite"); /* sliderClip = Gui.UIClip("MovieClip",{width:100, height:50, fillColor:0xFFFF0D, alpha:.7}); */ function UIClip (type:String, params:object = '') { var clip; trace("Hello") if (type == 'MovieClip') { clip = new MovieClip ; } else { clip = new Sprite; } //trace(params + "params.fillColor " + params.fillColor) if (params is Object) { clip.graphics.beginFill ((params.fillColor != "") ? params.fillColor : 0xFFFFFF, params.alpha ? params.alpha : 1 ); clip.graphics.lineStyle (params.lineThickness != "" ? params.lineThickness : 1, params.borderColor ? params.borderColor: 0x000000); clip.graphics.drawRoundRect (0,0, (params.width != undefined ) ? params.width : 100, (params.height != undefined) ? params.height : 100 , params.eW ? params.eW : 0, params.eH ? params.eH : 0); clip.graphics.endFill (); //trace("Hello") } return clip; } How can I solve this?
Condition "if (params is Object)" is true. String is object, too. I'm using null for optional params if they have no default value. Try this: function UIClip (type:String, params:object = null) and test "if (params != null)"