For while I am trying to call SQL Server 2008 R2 stored procedure using PetaPoco.
My stored procedure accepts a table valued parameter.
How I can call the stored procedure in petapoco with table value param?
Here what I am trying to do:
var db = new PetaPoco.Database("repikaciskaBaza");
DataTable table = new DataTable();
DataColumn id = table.Columns.Add("id", type: typeof(Int32));
for (int i = 0; i < 10;i++ )
{
DataRow row = table.NewRow();
row["id"] = i;
table.Rows.Add(row);
}
var param = new SqlParameter();
param.DbType = DbType.Object;
param.ParameterName = "#art_id";
param.SqlValue = table;
var lista = db.Query<pocoArts>(";exec dbo.test_sporc_param #0", param);
This code gives me an exception :
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect.
Parameter 3 ("#0"): Data type 0x62 (sql_variant) has an invalid type for type-specific metadata.
If I set parametar ty value
param.SqlDbType = SqlDbType.Structured;
Then I get exception like
The table type parameter '#0' must have a valid type name.
When I define my param like
param.SqlDbType = SqlDbType.Structured;
param.SqlValue = table;
param.ParameterName = "#art_id";
param.TypeName = SqlDbType.Structured.ToString();
Then I get exception
Column, parameter, or variable #0. : Cannot find data type Structured.
How I can define SqlParam with table valued param so I can send it whit data to SQL Server?
Solution:
var param = new SqlParameter();
param.SqlDbType = SqlDbType.Structured; // According to marc_s
param.SqlValue = table;
param.ParameterName = "#art_id";
param.TypeName = "dbo.typ_art_id"; // this is TYP from SQL Server database it needs to be equal to type defined in SQL Server not type of param
According to the relevant MSDN documentation on table-valued parameter, you should use:
var param = new SqlParameter();
param.SqlDbType = SqlDbType.Structured;
The SqlDbType.Structured is the key to this. Don't use DbType.Object.
Related
I am using pgp.helpers.insert to save data into PostgreSQL which is working well. However, I need to return values to present in a response. I am using:
this.collection.one(this.collection.$config.pgp.helpers.insert(values, null, 'branch'))
which returns no data.
What I want to be able to do is return the branch id after a successful insert, such as:
INSERT into branch (columns) VALUES (values) RETURNING pk_branchID
Simply append the RETURNING... clause to the generated query:
var h = this.collection.$config.pgp.helpers;
var query = h.insert(values, null, 'branch') + 'RETURNING pk_branchID';
return this.collection.one(query);
You must have a large object there if you want to automatically generate the insert. Namespace helpers is mostly valued when generating multi-row inserts/updates, in which case a ColumnSet is used as a static variable:
var h = this.collection.$config.pgp.helpers;
var cs = new h.ColumnSet(['col_a', 'col_b'], {table: 'branch'});
var data = [{col_a: 1, col_b: 2}, ...];
var query = h.insert(data, cs) + 'RETURNING pk_branchID';
return this.collection.many(query);
Note that in this case we do .many, as 1 or more rows/results are expected back. This can even be transformed into just an array of id-s:
return this.collection.map(query, [], a => a.pk_branchID);
see: Database.map
I have the filter logic parsed and put as a string in a variable called "where_clause". I have to use this where_clause in a query to fetch data.How can I use a string of this type after the where part of the query?I am working on salesforce with custom objects.
I suggest you check Dynamic SOQL.
In particular
String myTestString = 'TestName';
List<sObject> sobjList = Database.query('SELECT Id FROM MyCustomObject__c WHERE Name = :myTestString');
If you have your Custom Object as MyCustomObject__c
String myTestString = 'TestName';
List<MyCustomObject__c> sobjList = (List<MyCustomObject__c>)Database.query('SELECT Id FROM MyCustomObject__c WHERE Name = :myTestString');
I have an Access database which I need to retrieve all fields except the first and last and display it in a JTable. Everything works perfectly fine when I create my Object[][] but when i return it, i get a NullPointerException. I tried to find where there could be a null value in the database by printing the whole object out but that works fine and no values are null. Why would returning the Object[][] give me a NullPointerException and how can i fix it?
the stack trace is:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
public Object [] [] SetTrainingLogTable() throws SQLException
{
DatabaseConnection connection = new DatabaseConnection();
//Retrieves all the data from the TrainingLog table
ResultSet resultset = connection.SelectStatements("SELECT * FROM TrainingLog");
//Retrieves the number of entries
ResultSet numberofworkouts = connection.SelectStatements("SELECT COUNT(*) FROM TrainingLog");
int count = numberofworkouts.getInt(1);
number = count;
String[][] table = new String [count] [6];
//Number to incriment for while loops
int row = 0;
String date = "";
while(row<count)
{
date = resultset.getString(2);
table [row][0] = calculate.RefineDate(date);
table [row][1] = resultset.getString(3);
table [row][2] = resultset.getString(4);
table [row][3] = resultset.getString(5);
table [row][4] = resultset.getString(6);
table [row][5] = resultset.getString(7);
resultset.next();
row++;
}
Object[][] data = table;
connection.close();
return data;
}
I ran a debugger and it only gives the error when the return line is run.
It's best to post the stack trace and tell which line is raising the error. However, the typical way of writing such code is:
Connection con = ...;
Statement st = ...;
ResultSet rs = ...;
while (rs.next()) {
// ...
}
The result set starts out pointing before the first row. rs.next() returns whether there is a next row, and advances to it if it exists. Can you rewrite it in that style?
Other suggestions:
Can you create an actual object type instead of using Object[] to store the data from each row? Call it Workout.
Can you use a List<Workout> instead of your Object[][]?
Is the date stored in the database as a SQL DATE or TIMESTAMP? Then, don't convert it to a Java String: use java.sql.Date or java.util.Date. At work, I have a large old program that uses strings for dates, and it uses different formats to convert the values at different times. It's pretty miserable.
Don't use SELECT *. Give the names of the columns to return. Use the rs.getString("column_name") syntax.
There's no need to set one variable to the returned table and immediately set another variable to it.
Closing the connection or statement should be done in a finally block, or by try-with-resources.
I have simple stored procedure, that takes couple parameters and updates table.
How to pass parameters via BDC?
For example, to execute stored procedure, that selects rows and takes one param, code below.
BdcService bdcservice = SPFarm.Local.Services.GetValue<BdcService>();
IMetadataCatalog catalog = bdcservice.GetDatabaseBackedMetadataCatalog(SPServiceContext.Current);
// entity.GetLobSystem().GetLobSystemInstances()[0].Value;
IEntity entity = catalog.GetEntity(Utils.EntityNamespace, "GetMessage");
ILobSystemInstance lobSystemInstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value;
IFilterCollection filters = entity.GetDefaultFinderFilters();
ComparisonFilter filter = (ComparisonFilter)filters[0];
filter.Value = code;
IEntityInstanceEnumerator enumerator = entity.FindFiltered(filters, lobSystemInstance);
DataTable result = entity.Catalog.Helper.CreateDataTable(enumerator);
DataTable result contains selected rows.
But how to pass couple parameters to Update procedure?
BdcService bdcservice = SPFarm.Local.Services.GetValue<BdcService>();
IMetadataCatalog catalog = bdcservice.GetDatabaseBackedMetadataCatalog(SPServiceContext.Current);
// entity.GetLobSystem().GetLobSystemInstances()[0].Value;
IEntity entity = catalog.GetEntity(Utils.EntityNamespace, "ContractAdd");
ILobSystemInstance lobSystemInstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value;
// entity.ExecuteScalar();
entity has method "ExecuteScalar", but how to pass params via this method?
I am Unit Testing one of my functions. Here is my code:
public void TestLabels()
{
//Step 1: Creating a mock table with columns exactly like in the real table.
DataTable table = new DataTable();
DataRow mydatarow;
mydatarow = table.NewRow();
//Step 2: Adding the row as same as the Real Data!
mydatarow["Name"] = "Test";
mydatarow["Address"] = "00000 ST.";
mydatarow["ZipCode"] = "77665";
mydatarow["Tracking#"] = "";
table.Rows.Add(mydatarow);
foreach (DataColumn column in table.Columns)
Console.WriteLine(column.ColumnName);
//Step 3: Call method we are testing.
var updateTable = IceTechUPSClient.Instance.CreateLabels(table);
foreach (DataRow row in updateTable.Rows)
{
var trackingNumber = row["Tracking#"].ToString();
Assert.IsFalse(String.IsNullOrWhiteSpace(trackingNumber), "Expecting tracking number generated for every row!");
Assert.IsTrue(File.Exists(trackingNumber + ".gif"));
}
}
Now I am getting an error: Column 'Name' does not belong to table. As you can see I have specified column name "Name" here and also added that particular row. Then why I am getting this error? Any help?
Thanks!
You haven't set up your columns (unless you've missed out some code in your example).
You need to create the columns with the required names before you can access them like this:
var columnSpec = new DataColumn
{
DataType = typeof(string),
ColumnName = "Name"
};
this.table.Columns.Add(columnSpec);
When you read data from the database if you've set AutoGenerateColumns to true (the default) you don't need to do this explicitly as it's done for you behind the scenes.