我想使用数组从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(); }`
答案 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();
}