|
Hi,
CRecordSet::Update( ) is throwing the following exception.
Error:The cursor does not include the table being modified or the table is not updatable through the cursor
I donot know what could be the solution.
I am currently using SQL-Server 2005 ,VC++6.0 . Any help would be appreciated.
Thanks
|
|
|
|
|
|
This user is a habitual cross-poster. This message is in THREE forums.
Blog link to be reinstated at a later date.
|
|
|
|
|
hi ,
i make simple method that retrieve data from tables this is easy but my problem happen when i retrieve data from table that have relationship with other table, i make class to set value into properties when i read and bind it in Gridview.
i make for each table class that contains to properties and if i make all table in one class it work so i want to find solution to it with do this.
Tables
Create Table Catgerories (
CatgId int PRIMARY KEY,
Catgname nvarchar(50)
)
Create Table StudentInfo(
stId int PRIMARY KEY,
Stname nvarchar(50),
CatgId int REFERENCES Catgerories (CatgId)
)
create PROCEDURE dbo.StoredProcedure2
AS
SELECT StudentInfo.*, Catgerories.Catgname
FROM Catgerories INNER JOIN
StudentInfo ON Catgerories.CatgId = StudentInfo.CatgId
RETURN
Code:
public class CatgBL
{
int cid = 0;
public int Cid
{
get { return cid; }
set { cid = value; }
}
string catgName;
public string CatgName
{
get { return catgName; }
set { catgName = value; }
}
}
public class MyStudent
{
int stid;
public int Stid
{
get { return stid; }
set { stid = value; }
}
string sname;
public string Sname
{
get { return sname; }
set { sname = value; }
}
int catgid;
public int Catgid
{
get { return catgid; }
set { catgid = value; }
}
}
SqlConnection myCon = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Documents and Settings\Administrator\My Documents\TestDb.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
public ArrayList RetriveStdentInfo()
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = myCon;
cmd.CommandText = "dbo.StoredProcedure2";
cmd.CommandType = CommandType.StoredProcedure;
myCon.Open();
IDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
ArrayList sequence = new ArrayList();
ArrayList seqCat = new ArrayList();
ArrayList seqStudent = new ArrayList();
while (reader.Read())
{
MyStudent std = new MyStudent();
CatgBL cat = new CatgBL();
std.Stid = reader.GetInt32(0);
std.Sname = reader.GetString(reader.GetOrdinal("stname"));
std.Catgid = reader.GetInt32(reader.GetOrdinal("Catgid"));
cat.CatgName = reader.GetString(reader.GetOrdinal("CatgName"));
seqCat.Add(cat);
seqStudent.Add(std);
sequence.AddRange(seqStudent);
sequence.AddRange(seqCat);
}
return sequence;
}
|
|
|
|
|
I'm not sure if I understood you correctly, but I think you have two choices.
1. when looping through rows, create a new object for category only when the primary key changes. Because you have joined the data when fetching, you will have the same category multiple times.
2. fetch categories and students separately.
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
Thanks for you,may be i understand some things but i have some lack in ur soltion , i do this changes in code but the problem is still
public ArrayList RetriveStdentInfo()
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = myCon;
cmd.CommandText = "dbo.StoredProcedure2";
cmd.CommandType = CommandType.StoredProcedure;
myCon.Open();
IDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
ArrayList sequence = new ArrayList();
ArrayList seqCat = new ArrayList();
ArrayList seqStudent = new ArrayList();
while (reader.Read())
{
CatgBL cat = new CatgBL();
cat.CatgName = reader.GetString(reader.GetOrdinal("CatgName"));
seqCat.Add(cat);
seqCat.Add(cat);
}
while (reader.Read())
{
MyStudent std = new MyStudent();
std.Stid = reader.GetInt32(0);
std.Sname = reader.GetString(reader.GetOrdinal("stname"));
std.Catgid = reader.GetInt32(reader.GetOrdinal("Catgid"));
seqStudent.Add(std);
}
sequence.AddRange(seqCat);
sequence.AddRange(seqStudent);
return sequence;
}
|
|
|
|
|
That's not quite what I meant. Something like this:
int prevCatId = 0;
while (reader.Read())
{
MyStudent std = new MyStudent();
std.Stid = reader.GetInt32(0);
std.Sname = reader.GetString(reader.GetOrdinal("stname"));
std.Catgid = reader.GetInt32(reader.GetOrdinal("Catgid"));
if (prevCatID != reader.GetInt32(reader.GetOrdinal("Catgid")))
{
CatgBL cat = new CatgBL();
cat.CatgName = reader.GetString(reader.GetOrdinal("CatgName"));
seqCat.Add(cat);
prevCatID = reader.GetInt32(reader.GetOrdinal("Catgid"));
}
seqStudent.Add(std);
sequence.AddRange(seqStudent);
sequence.AddRange(seqCat);
}
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
Thanks again but the problem is still running
Object does not match target type
when i make debugging code the result is right but the problem appear in binding
StudentDAL std = new StudentDAL();
DataGrid1.DataSource = std.RetriveStdentInfo();
DataGrid1.DataBind();
|
|
|
|
|
I'm not sure if DataGrid can handle two dimensional arrays. Since you return an arraylist which contains arraylists, it can be problematic.
I also noticed that you add the same elements several times. That can also cause problems. Move the following lines outside the read loop:
sequence.AddRange(seqStudent);
sequence.AddRange(seqCat);
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
|
The situation in the article is a little bit different. When you setup an array of entities, all entities have properties, so now you have used two dimensions (for example if student is a row and name property is a column).
What kind of layout are you trying to achieve in DataGrid? Something like the following?
PersonID Name Age
1 John 32
2 Kendra 20
3 Steve 29
...
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
|
Okay,
then you have modify your method so that you return an arraylist that contains only instances of one class. Now you return an arraylist that contains nested arraylists and I don't believe it will work.
If your layout should be like that, my original reply is misleading. You should combine CatgBL and Student classes to one class only. After that you can create instances of that class to an arraylist and then return the list and display it.
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
Thanks for u to be interested to help me to correct code to work well but i say when i post the question " if i make all table in one class it work" and what motivate me to find solution and make each classes are separated is that when i make all attributes in one class this make problem if i want to display the data of any table only without display other so if i do this when i add object, the other attributes which i skip from class give default values to skipped values by zero so this force me to make one class for the state of joining when i want to display record that have a relation with other table and make one when i want to display the data of one table. ,thanks again for u and may Allah bless u for u effort.
|
|
|
|
|
Basically there is nothing wrong if you keep the data in two separate classes like in the first post. The problem is mainly in DataGrid.
Perhaps you could use more powerful DataGridView instead. With that control you could create a combo box column for category so you wouldn't have problems with empty foreign key properties. This way you could have a combobox for user to select what category he wants to use for a person and if category is selected, it will be shown.
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
I Make some changes in code and data displayed but not displayed in normal form but each data in column displayed in row and no header text to columns.and the question also if i make another method to update data , my work is to do changes in destination array and compare the id that hold in array with the record in db and apply changes or wat?
public ArrayList RetriveStdentInfo()
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = myCon;
cmd.CommandText = "dbo.StoredProcedure2";
cmd.CommandType = CommandType.StoredProcedure;
myCon.Open();
IDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
ArrayList seqCat = new ArrayList();
ArrayList seqStudent = new ArrayList();
<code>ArrayList destnation = new ArrayList();</code>
int prevCatId = 0;
while (reader.Read())
{
MyStudent std = new MyStudent();
std.Stid = reader.GetInt32(0);
std.Sname = reader.GetString(reader.GetOrdinal("stname"));
std.Catgid = reader.GetInt32(reader.GetOrdinal("Catgid"));
if (prevCatId != reader.GetInt32(reader.GetOrdinal("Catgid")))
{
CatgBL cat = new CatgBL();
cat.CatgName = reader.GetString(reader.GetOrdinal("CatgName"));
seqCat.Add(cat);
prevCatId = reader.GetInt32(reader.GetOrdinal("Catgid"));
}
seqStudent.Add(std);
}
<code> foreach ( MyStudent var in seqStudent)
{
destnation.Add((int)var.Catgid);
destnation.Add((string)var.Sname);
destnation.Add((int)var.Stid);
}
foreach (CatgBL var in seqCat)
{
destnation.Add((int)var.Cid);
destnation.Add((string)var.CatgName);
}
return destnation;</code>
}
|
|
|
|
|
|
you can use constraint on C# code to joid two tables
|
|
|
|
|
but why ? and what is the benefit if i do ?
|
|
|
|
|
can you explain your problems
|
|
|
|
|
go to the Subject , i explain the problem and code also.
|
|
|
|
|
I have got a table say something like this:
ID VARCHAR(30),
ParentID VARCHAR(30),
TITLE NVARCHAR(100)
As it seems, this table has a parent-child relation with itself. the ID column is not auto-generated and is a combination of ASCII characters and numbers with length of 30.
Now, I want to move all the data contained in the above table to the following table:
ID SMALLINT
ParentID INT
TITLE NVARCHAR(100)
In this table, ID is an auto-generated integer Identity column starting from 1.
What is the best way for converting the ID columns while moving them to the new table?
Thanks in advance for any help
|
|
|
|
|
I think you have to do this in two parts. If you have a natural key on the table, it's easiest to use that. Something like (just a draft, may contain several mistakes):
INSERT INTO TargetTable (Title)
SELECT Title
FROM SourceTable
--
UPDATE TargetTable
SET ParentID = (SELECT tt1.Id
FROM TargetTable tt1, SourceTable st1, SourceTable st2
WHERE targettable.Title = st1.Title
AND st2.Id = st1.ParentId
AND st2.Title = tt1.Title)
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|
|
Thank you, seems a very good idea. I will try it
|
|
|
|
|
You're welcome
The need to optimize rises from a bad design.
My articles[ ^]
|
|
|
|