从Access数据库中删除多行

时间:2011-01-25 14:17:09

标签: c# arrays ms-access

我想使用数组从access数据库中删除多条记录。 该数组是从文件名动态加载的。

然后我查询数据库,看看数据库列值是否与数组值匹配,如果没有则删除它,如果匹配则不删除它。

问题在于: 以下是删除所有记录的代码,与条件中的位置无关。

arrays = Directory.GetFiles(sdira, "*", SearchOption.AllDirectories).Select(x => Path.GetFileName(x)).ToArray();
    fnames.AddRange(arrays); 

    here I have use also for loop but that also didnt help me out :( like for(int u = 0; u < arrays.length; u++) { oledbcommand sqlcmd = new oledbcommand ("delete from table1 where name not in ("'+arrays[u]+"')",sqlconnection);
   I am using this one currently foreach(string name in arrays)
   {
       OleDbCommand sqlcmd = new OleDbCommand("delete from table1 where name not in ('" + name + "')", sqlconnection);
       sqlcmd.ExecuteNonQuery();                                  }`

6 个答案:

答案 0 :(得分:6)

一个问题是您的代码令人困惑。

string [] a = {"" 'a.jpg', 'b.jpg', 'c.jpg' "}

首先,你有两个“开头,应该只有一个。”

string [] a = {" 'a.jpg', 'b.jpg', 'c.jpg' "}

然后这创建了一个包含一个元素的字符串数组

a[0] = "'a.jpg', 'b.jpg', 'c.jpg'";

然后你对这个做了一个foreacharly ony执行一次导致这个查询:

delete from table1     where name not in ('a.jpg', 'b.jpg', 'c.jpg')

但是当您动态加载数组时,您可能会获得此数组

a[0] = 'a.jpg';
a[1] = 'b.jpg';
a[1] = 'c.jpg';

将在foreach中执行3次,导致以下3次查询

delete from table1     where name not in ('a.jpg')
delete from table1     where name not in ('b.jpg')
delete from table1     where name not in ('c.jpg')

在第二个之后,该表将为空。

你应该试试这个:

string[] names = { "a.jpg", "b.jpg","c.jpg","j.jpg" };
string allNames = "'" + String.Join("','", names) + "'";

OleDbCommand sqlcmd = new OleDbCommand("delete from table1  where name not in (" + allNames + ")", sqlconnection); 
sqlcmd.ExecuteNonQuery(); 

其中名称是动态创建的,这将导致以下查询与您的测试匹配:

delete from table1     where name not in ('a.jpg', 'b.jpg', 'c.jpg')

我动态填充数组的首选方法是使用列表,因为纯数组的大小是固定的,任何更改都需要创建一个新数组。

您可以将列表作为数组循环遍历。

List<string> names = new List<string>();
//or user var keyword
var names = new List<string>();

然后只需使用add方法添加元素,根据需要循环。

names.Add(filename);

然后连接:

string allNames = "'" + String.Join("','", names.ToArray()) + "'";

你已经完成了。

或者你可以使用

string[] filePaths = Directory.GetFiles(@"c:\MyDir\", "*.jpg");
string[] names = filePaths.ToList().ConvertAll(n => n.Substring(n.LastIndexOf(@"\") + 1)).ToArray();

答案 1 :(得分:1)

将我的评论作为答案发布

你的字符串没有读入4个条目,它读取一个条目

string names = " 'a.jpg', 'b.jpg','c.jpg','j.jpg' ";

应该是

string[] names = { "a.jpg", "b.jpg","c.jpg","j.jpg" };

在每个人的计数为1之前,它应该具有实际值的计数值

编辑: 我必须承认,在这个解决方案中没有太多的努力,但如果你想要动态输入可以做类似的事情:

    string name = " 'a.jpg', 'b.jpg','c.jpg','j.jpg' ";
    string[] names = name.Split(',').Select(x => x.Trim(' ').Trim('\'')).ToArray();
如果由于修剪效果不佳而

我将得到更改,

将会更新

为了填充它,如果你想要它可枚举一个例子可能是像

IEnumerable<string> filelocations = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories).Select(x => Path.GetFileName(x));

或用于字符串数组

string [] lok = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories).Select(x => Path.GetFileName(x)).ToArray();

答案 2 :(得分:0)

听起来你要么没有正确读取文件,要么文件是空的。在对数据库运行操作之前,您应该检查数组以确保它不为空。如果数组为空,它应该删除数据库中的所有内容,因为没有匹配项。

答案 3 :(得分:0)

您需要像这样定义数组:

string[] names = { "a.jpg", "b.jpg", "c.jpg", "j.jpg" };

您定义数组的方式只包含一个值:

" 'a.jpg', 'b.jpg','c.jpg','j.jpg' "

答案 4 :(得分:0)

评论中的代码将删除与第一个文件不匹配的任何文件。这将是所有非'a.jpg'文件。下一次迭代将删除所有与'b.jpg'不匹配的文件,即'a.jpg'。这导致一个空表。 编辑:手动执行此操作时,您所拥有的数组声明会生成一个良好的IN子句,但是当您获得文件名列表时,您不会生成相同的字符串。< / p>

您需要在数组上执行连接,以便为where子句生成单个字符串,其方式是where子句包含所有文件。你的终极where子句应该是这样的:

where name not in ('a.jpg','b.jpg','c.jpg','d.jpg')

现在你有:

where name not in ('a.jpg')

...下一次迭代

where name not in ('b.jpg')

另外,请注意IN操作费用昂贵,数组越长,查询增长的速度越快。

答案 5 :(得分:0)

如果您不想创建静态大小的数组,请尝试使用列表

List<string> names = new List<string>();
names.Add("a.jpg");
names.Add("b.jpg");
names.Add("c.jpg");


foreach (string name in names)
{
   OleDbCommand sqlcmd = new OleDbCommand("delete from table1 
   where name not in (" + name + ")", 
   sqlconnection); 
   sqlcmd.ExecuteNonQuery(); 
}