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.
Related
I never should've expected that knowing mySQL I'd be safe using Access.
I have two tables: users and scores
users table contains: id(auto increment primary key), username, password, etc..
scoers table contains: id(number - foreign key to users.id), highScore
I've previously asked help for INSERT command, which now works as it should. Now I've got issues with a similar UPDATE command.
The non-working command looks like this:
string updateCommand = #"UPDATE scores
SET
id = (SELECT id FROM users WHERE username = #username),
highScore = #score
WHERE highScore = (SELECT MIN(highScore) FROM scores);";
which throws a: Operation must use an updateable query.
To rationalize what I'm trying to accomplish here: I'm INSERT-ing high scores until I reach 10 scores in the table, afterwards instead of adding any new scores and filling up the database needlessly I decided It'd be more sensible to just "overwrite" the currently lowest score using UPDATE.
I am supplied a username and the high score and since the scores table contains only id I need to reach the id of the current user so that's what the first subquery is doing, the second subquery in the WHERE clause is to specify which score to replace (though there is possibly a bug here if there are multiple people with the lowest score, any ideas how to fix that?)
I've also tried using OUTER RIGHT JOIN like this:
string updateCommand = #"UPDATE scores
OUTER RIGHT JOIN users ON scores.id = users.id
SET
scores.id = users.id,
scores.highScore = #score
WHERE (highScore = (SELECT MIN(highScore) FROM scores)) AND (username = #username);";
With no luck(I get a generic Syntax error in UPDATE statement.).
Browsing the net I've found that I possibly "can't" use subqueries in UPDATE statements but I seem to find conflicting opinions on the matter.
I've also tried using the DLookup function in place of subqueries like:
#"...
id = DLookup(""id"", ""users"", ""username = #username""),
...
WHERE highScore = DLookup(""MIN(highScore)"", ""scores"");";
elipses represent extraneous code which is identical to the code above.
Also as a last resort I've tried dividing into multiple queries however userId query which looks like this:
string userIdQuery = "SELECT id FROM users WHERE username = #username"
seems to return a null judging by the NullReferenceException i recieve (Object reference not set to an instance of an object.) when trying to use the variable userId after I've done this:
int userId = 0;
userId = (Int32)command.ExecuteScalar();
I'm supposed to get an integer however I get a null I think. The almost identical query for getting the minimum highscore works flawlessly and the int variable is filled with the correct value so I'm assuming that hte problem is in the query itself somehow. I've tried adding single quotes around the #username parameter assuming that it might not be recognizing the string but it seems that's not it.
Phew.. took me a while to write this. Anyone got any ideas on how to make this all work? If you need more info let me know.
So after some messing around I've found out the causes of my troubles. The bad side is that I increased the amount of code so that I'd avoid subqueries as much as possible since, at least from my experience, Access doesn't really like the use of subqueries in UPDATE or INSERT commands.
What I did first is split the command into 3 separate ones:
"SELECT id FROM users WHERE username = ?;" - To get the id of the user whose score
I'm putting in the database.
#"SELECT scores.id, scores.highScore, scores.dateTime FROM scores WHERE (((scores.highScore)=DMin(""highScore"",""scores"")));" - which gets the id, high score
and time when the entry was... well entered, of the lowest score currently in the high scores list. Thanks to a suggestion from HansUp I used DMin function instead of a subquery with MIN to avoid the Must use an updateable query error. The extraneous parentheses are due to Access since this command was generated by the Access query designer and I'm too afraid to change anything lest I break it.
#"UPDATE scores SET scores.id = ?, scores.highScore = ?, scores.[dateTime] = Now() WHERE (((scores.id)=?) AND ((scores.highScore)=?) AND ((scores.dateTime)=?));" - The update command itself, not much to say here except that it takes the previously extracted data and uses it as values for the command.
One thing I noticed is that even if I got the command working the .ExecuteNonQuery() would always return 0 rows affected. After poking around I found out that named parameters for commands in ASP.NET / C# don't always work and that instead ? should be used instead. It's kind of inconvenient but I can't complain too much.
I am writing a code that calls a column from a dataset using a SQL query. I use two parameters to identify which rows to select. One is the ProductSerialNumber, and the other is a datetimestamp. See my SQL query below
Select TestStation FROM tblData
WHERE ProductSerialNumber = ? AND Datetimestamp = ?
In the dataset's datatable the productserialnumber is formatted as text, and the other is formatted as a date (as you would expect).
In my vb.net code, I grab the Datetimestamp from another source (don't ask why, the only thing you need to know is that it grabs a valid datetimestamp, dimensioned as a date, that matches exactly with the tblData's entry) and I use the premade query to generate a datatable. The query is a Fill query called "TestStationLookUp"
my vb.net code looks like this
Dim dt as new dataset.tbldataDataTable
Dim dta As New DataSetTableAdapters.tbldataTableAdapter
Dim ProductSerialNumber as string = "XXXXXX"
Dim DateTimeStamp as date = SomeDateVariable
dta.TestStationLookUp(dt, ProductSerialNumber, DateTimeStamp)
It is here that the code tells me:
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
Line 7366: dataTable.Clear
Line 7367: End If
Error: Line 7368: Dim returnValue As Integer = Me.Adapter.Fill(dataTable)
Line 7369: Return returnValue
Line 7370: End Function
I cannot understand why this error arises, as everything is dimensioned the way it should be. This exact code setup works elsewhere in my code (except it doesn't use a date), but this specific piece won't work.
Also, if I go to the dataset in my solution, I can use the "preview data" on this query and type in the EXACT same parameters (the ProductSerialNumber and DateTimeStamp that match the record in the table AND what I use in my vb code) and it will give me produce the table I want.
Can anyone assist?
This error means that you are trying to access not valid unique id "ProductSerialNumber", maybe it does not exist
Failed to enable constraints. One or more rows contain values
violating non-null, unique, or foreign-key constraints.
Instead of passing the variable that comes from dataset ,pass a valid number that you are sure it exists in database
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
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
I'm using TableAdapters on my ASP.NET Project and I've become stuck on an issue of the way to retrieve this data.
The code is as follows:
BookingDataTableAdapters.bookingTableAdapter ta = new BookingDataTableAdapters.bookingTableAdapter();
String booking_id_string = Request["id"];
int booking_id = Int32.Parse(booking_id_string);
BookingData.bookingDataTable table = ta.GetOwnerUsername(booking_id);
String username = string.Empty;
foreach (DataRow dr in table.Rows)
username = dr[0].ToString();
However this will error with the following:
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
However when I run the query in the query builder, it runs fine without error. I've have also disabled "EnforceConstraints" inside the table adapter xsd file properties.
I've no idea what's wrong, is there a better way for me to get this single value back from my query in ASP.NET
Many thanks in advance, I appreciate the help :-)
What that tells me is that BookingData has been changed in the database and the object in your project was not updated. When you get the row it cant fill the object because perhaps the database has a null and the object does not allow it. Update the dataset.