Using a SQL Function to Format Account info? - asp.net

I have a SQL function that I am calling in my VB.Net code within a display function. The SQL function will format my account data to include the following results form a Table.
The table data: "001000011121" (this is the type of structure the data has before formated)
So the data table data and vb Properties would be called Myaccount, HerAccount, ThisAccount.
Once the data is pulled and then formatted in the VB.net code it will result into a GridDisplay as as: "001.00.001.1121"
The way I have my Public Function in my code is:
Public Funcion GetDisplay(_
ByVal dbBass as DataProvider_
,ByVal pps AS TMGDatarequestParms_
,By filter As IFilter_
) As Ilist
Dim strobe As String = CType(parms.OptionalParameters, DataProvider).Database
Dim sql As BiGSqlBuilder(TABLE)
sql.Select = String.Format("ID, [{0}].dbo.GLForamtAcct(Myaccount) AS [Myaccount], [{0}].dbo.GLFormatAccount(HerAccount) AS [HerAccount], [{0}].dbo.GLFormatAccount(ThisAccount) AS [ThisAccount]", strobe)
I left out some of the return code since not necessary. The only thing I'm concerned is how to format the SQL within the VB.net Code above. I hope this makes sense I'm new to this whole abstraction stuff. Any help would be Highly appreciated cause I'm pretty sure how I have it above does not work.

Suggest implementing your display code in your higher tiers, rather than burdening your database with this business logic.
It sounds like you're string to use String.Format() to insert the table name in your string. This syntax of database.schema.object is really only needed if performing cross database calls.
If you really want to use your SQL UDF to perform your formatting, suggest using/formulating a SELECT statement like:
SELECT ID,
dbo.GLFormatAccount(Acct1) AS Acct1,
dbo.GLFormatAccount(Acct2) AS Acct2,
dbo.GLFormatAccount(Acct3) AS Acct3
FROM MyTable

Related

How can I more efficiently deal with DBNull.value in vb.net / SQL Server

I have a class type object, such as:
Private Class Car
Public Property Make As String
Public Property Model As String
Public Property Used As Boolean?
Public Property Mileage As Integer?
Public Property DateSold As Date?
End Class
I'm parsing a query string that's posted to my page that may or may not have key/value pairs for the above properties. For example, it may just be:
?Make=Toyota
I have a table in SQL Server based on the Public Properties you see above, and I'm allowing NULLS on all columns. (My real data has more fields, so this is for explanation purposes)
CREATE PROCEDURE InsertCar
#Make varchar(25),
#Model varchar(25),
etc.
I'm not setting default values in the parameters in the stored procedure above. I want to know of a cleaner way to do this from code.
For example:
The data is posted to my page... I use httputility to parse it, and I can build a new object, such as:
Dim record As New Car
record.Make = Data("make")
record.Model = Data("model")
record.Used = Data("used")
record.Mileage = Data("mileage")
record.DateSold = Data("datesold")
Afterwards, I build some parameters for my stored procedure, but here's where I think I can improve:
Dim pars As New List(Of SqlParameter)
pars.Add(New SqlParameter("#Make", If(record.Make = Nothing, DBNull.Value, record.Make))
and so on...
So you can see my ternary operators for building the parameters. Is there a cleaner way, perhaps using default values or when the class is being put together to make this cleaner?
This is more of a precision and best practice question I think. Should I be assigning DBNull.Value to the public properties? Or is how I'm doing it sufficient? Is there a cleaner way to map nullable properties?
My values from the query string are parsed into a NameValueCollection, so is there an easier way to just iterate over the ones that exist, and if not exist in the class, automatically build the parameter with DBNull.Value?
I hope my question makes sense. With a lot of data it just seems ugly with all the if/then DBNull.value, etc. I feel like I could be saving myself a step somewhere along the way. The class object is helpful for organization and is utilized in other parts of the code, or else I'd probably just build the parameters and be done with it.
You can set default values in the stored procedure parameters.
CREATE PROCEDURE InsertCar
#Make varchar(25) = null,
#Model varchar(25) = null
...
And just pass your object, if it is null/missing the stored proc will default the missing paramater value to null
pars.Add(New SqlParameter("#Make", record.Make))
The SQL table also needs to accept nulls.
Or, use the vb.net IF() operator with 2 parameters
pars.Add(New SqlParameter("#Make", If(record.Make,DBNull.Value))
Is there a VB.NET equivalent for C#'s '??' operator?

Getting Table Field Names as a String

I'm trying to get the list of field names for a given table, to turn them into a string which I can to post back as a variable to another function.
I've Googled loads of stuff regarding GetSchemaTable but all I seem to be able to output are field parameters, but not the actual value of these parameters (ie ColumnName, which is the one I actually want!)
Found this page; What is the SQL command to return the field names of a table?
But all the queries on there give me an error "You do not have access to Table 'Columns'"
I feel sure this is pretty simple, can someone give me a little function that will simply give me
fieldNames = "fieldName1, fieldName2, etc"
I am using a MySQL server and ODBC connections ASP.NET using VB.
I don't know if this will work, but give it a try.
Instantiate a OdbcCommand with something like select * from yourtable limit 0;
Load a DataTable with the datareader returned from cmd.ExecuteReader.
DataTable dt as new DataTable()
dt.Load(cmd.ExecuteReader())
Now iterate through the columns of dt to find out what the column names are.
This is just and idea. Don't know if it will work or not.

Working with parameterized stored procedure in ASP.NET

So, my SQL Server admin has given me access to a stored procedure with 5 parameters that returns 15 columns of data.
However, if I want to filter on the columns that are not parametrized, I have just a few options. Creating a DataSet does not help, since the query to the database can only be the stored proc and it's parameters, not Select statements.
I can create an XML file and query that using Linq-to-XML
I can create some temporary tables in another database and query those
What am I missing?
some ideas...
1) Can you ask your dba for a new stored procedure that filters (using additional parameters) on columns you need to filter on?
2) Can you write your own stored procedures? If so, you could, for example declare a table variable, insert into it using an exec on the stored procedure your dba wrote, and then select from it using any filters you like.
3) re: your two options -- those will work -- you can pull all of the data into a datatable in asp.net, or an xml file, but that's moving and exposing data you know at design time you won't need, so not an ideal solution.
4) Can you directly query the table(s) yourself?
EDIT
You can bring (all) of the data into a datatable (asp.net), and then filter it there. For example (VB):
Dim myFilter as String
myFilter = "SomeField = SomeValue"
Dim myRows() as datarow
myRows = myDataSet.Tables(i).Select(myFilter)
For each myRow as datarow in myRows
myNewDataTable.ImportRow(myRow)
Next
It's not ideal, but considering the limitations...
Creating a DataSet does not help, since the query to the database can
only be the stored proc and it's parameters, not Select statements.
A DataSet can be filled using a stored procedure. When you filled up your DataSet then you filter the records using whatever data access technology you know/like.
marc_s is right, get a new DBA. If he doesn't want to create a stored procedure or add parameters to the existing procedure then he probably won't mind your application getting 1,700 records every time you call that stored procedure when all you really need is a subset of those records.
You can bring the data back into a DataSet and then use a DataView object to apply a filter. In short, this will call the stored procedure, gather all of the rows into the DataSet, and then the DataView will let you enumerate the data skipping over rows that don't match the filter.
Here's an example in C#: C# DataView Usage
If the number of records you get back is not huge, you could do this:
Create a POCO class to represent the data record coming back from the stored proc:
public class MyRecord
{
Field1Name { get; set;}
...
Field10Name { get; set;}
}
Populate a List<MyRecord> with the results coming back from your stored proc:
List<MyRecord> mylist = new List<MyRecord>();
foreach(record in collectionOfRecordsFromStoredProc)
{
mylist.Add(new MyRecord {
Field1Name = "", /* retrieve your value from record here */
...
Field10Name = "" /* retrieve your value from record here */
});
}
Then you can query those results using the standard Linq to Objects:
List<MyRecord> filteredRecords = mylist.Where(x => x.Field10Name.Contains("Smith")).ToList();
This essentially will do everything in memory without an intermediaray place to persist the data. But this will not scale well if you are expecting to receive very large numbers or records back from this stored proc.
NOTE: code above is untested so will probably need tweaking

Multivalued parameter within T-SQL Query

I am working on .aspx page that uses a t-sql query that uses a multivalued input parameter (a set of labnames) using an array that would store all the labnames prior to running the query.
I have the following parameters for the query.
With c.Parameters
.Add(New SqlParameter("#sdate", sdate.text))
.Add(New SqlParameter("#edate", edate.text))
.Add(New SqlParameter("#labname", SqlDbType.Text)).Value = labnamesparam.ToString
End With
However, I still see that only one labname (3rd param in the order).
Any ideas on this?
For SQL 2008 your should use a TVP, as recommended by Marc.
For SQL 2005 there are several techniques like using XML or using a comma delimitted list. A comprehensive analysis of each technique is kept by Erland Sommarskog on hi page at http://www.sommarskog.se/arrays-in-sql-2005.html.
For SQL 2000 the options are fewer, and again Erland has a comprehensive discussion of each at Arrays and Lists in SQL Server (SQL 2000 and Earlier).
I highly recommend Erland's articles, they've been the reference on the subject for many years now.
You need to turn the contest of the array into a string. Here is a c# example, certainly not the only way to do it.
System.Text.StringBuilder k = new System.Text.StringBuilder();
foreach (string x in LABNAMES) {
k.Append(x);
k.Append(",");
}
.Add(New SqlParameter("#labname", SqlDbType.Text)).Value =k.ToString();
Your going to have to change your sql though you can't have a dynamic in clause like that. Old trick but not good practice is to turn the whole sql into a string and do an execute one it.
You might have to do a little bit more work in your stored procedure if you want to pass along an array of strings to it and perform a T-SQL "IN" operation.
This article has a very good example.
IF you use SQL Server 2008, you could use the "table-valued parameter" (TVP) feature.
Basically, in SQL Server 2008, you need to define a user-defined table type:
CREATE TYPE Customer AS
TABLE (id int, CustomerName nvarchar(50), postcode nvarchar(50))
and then use that in your stored procedure as a parameter:
CREATE Procedure AddCustomers(#customer Customer READONLY)
And then in your C# code, you'd create a DataTable variable of the same structure, and use that as the input parameter. That way, you can pass in any number of values, and any structure you like.
See these excellent blog posts for more information and extensive code samples:
Guy Burstein
Ben Hall
SQL-Team
Marc

Asp.net fulltext multiple search terms methodology

I've got a search box that users can type terms into. I have a table setup with fulltext searching on a string column. Lets say a user types this: "word, office, microsoft" and clicks "search".
Is this the best way to deal with multiple search terms?
(pseudocode)
foreach (string searchWord in searchTerms){
select col1 from myTable where contains(fts_column, ‘searchWord’)
}
Is there a way of including the search terms in the sql and not iterating? I'm trying to reduce the amount of calls to the sql server.
FREETEXT might work for you. It will separate the string into individual words based on word boundaries (word-breaking). Then you'd only have a single SQL call.
MSDN -- FREETEXT
Well you could just build your SQL Query Dynamically...
string [] searchWords = searchTerm.Split(",");
string SQL = "SELECT col1 FROM myTable WHERE 1=2";
foreach (string word in searchWords)
{
SQL = string.Format("{0} OR contains(fts_column, '{1}')", SQL, word);
}
//EXEC SQL...
Obviously this comes with the usual warnings/disclaimers about SQL Injection etc... but the principal is that you would dynamically build up all your clauses and apply them in one query.
Depending on how your interacting with your DB, it might be feasible for you to pass the entire un-split search term into a SPROC and then split & build dynamic SQL inside the stored procedure.
You could do it similar to what you have there: just parse the search terms based on delimiter, and then make a call on each, joining the results together. Alternatively, you can do multiple CONTAINS:
SELECT Name FROM Products WHERE CONTAINS(Name, #Param1) OR CONTAINS(Name, #Param2) etc.
Maybe try both and see which is faster in your environment.
I use this class for Normalizing SQL Server Full-text Search Conditions

Resources