iOS数据库进级,SQL数据库间歇性至极

在运作程序以前需求在mysql数据库中开创test数据库,如下图所示:图片 1

近几来重新管理了瞬间项目中数据库进级的豆蔻梢头对,把思路和落到实处多少记录一下。

C# SQL数据库间歇性至极 A network-related or instance-specific error
呼救!原来安静运营意气风发段时间的主次忽然现身SQL数据库连接十分
先后特别音讯 如下

上面是现实是兑现程序:

关于数据库升级,首先大家需求二个常量,来标志作者的数据库版本号应该是不怎么

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

  

//2017年7月1号第1版 (指定的一个数据库的版本号)
static int kDBVersion = 2017070101;
  1. 能够ping到长途数据库服务器的ip
  2. 动用SQL Server 二零一四 Management Studio无法连接到长途数据库 (分外提醒与程序少之又少年老成致卡塔尔国,但本地的数据库能够连接上
  3. 重启本机后得以平常连接远程数据库
  4. 程序是定时央求数据库视图 大致是间隔10分钟诉求一次
  5. 当前只是那台Computer留慰藉题,有运营本程序越来越持久的计算机 未有现身过相似意况
  6. 运作程序的Computer系统是Server 2009、当地数据库是 Server 2010牧马人2、远程数据库的本子不精晓
  7. 长途数据库应该没难点 因为这个时期局域网内其余Computer能够平常访谈
  1 package News;
  2 
  3 import java.sql.Connection;
  4 import java.sql.DriverManager;
  5 import java.sql.ResultSet;
  6 import java.sql.Statement;
  7 import java.util.Scanner;
  8 
  9 public class News {
 10     public static void main(String[] args) {
 11         System.out.println("< < < < < < 使用ArrayList实现新闻管理系统 > > > > > >");
 12 
 13         while (true) {
 14             Scanner scanner = new Scanner(System.in);
 15             System.out
 16                     .println("1. 查询全部新闻n2. 添加新闻n3. 删除新闻n4. 按标题查询新闻n5. 按标题修改新闻 n0.退出n请选择功能(1,2,3,4,5,0):");
 17             int selected = scanner.nextInt();
 18 
 19             switch (selected) {
 20             case 1:
 21                 reads();
 22                 break;
 23 
 24             case 2:
 25                 System.out.println("请输入新闻标题:");
 26                 String title = scanner.next();
 27                 System.out.println("请输入新闻内容:");
 28                 String content = scanner.next();
 29                 System.out.println("请输入新闻备注:");
 30                 String remark = scanner.next();
 31 
 32                 add(title, content,remark);
 33                 break;
 34 
 35             case 3:
 36                 System.out.println("请输入新闻标题:");
 37                 String title2 = scanner.next();
 38                 delete(title2);
 39                 break;
 40 
 41             case 4:
 42                 System.out.println("请输入新闻标题:");
 43                 String title1 = scanner.next();
 44                 read(title1);
 45                 break;
 46 
 47             case 5:
 48                 System.out.println("请输入新闻标题:");
 49                 String title3 = scanner.next();
 50                 update(title3);
 51                 break;
 52 
 53             case 0:
 54                 scanner.close();
 55                 System.exit(0);
 56                 break;
 57 
 58             default:
 59                 System.out.println("输入错误,请重新输入:");
 60                 break;
 61             }
 62         }
 63     }
 64 
 65     /**
 66      * 定义添加新闻方法
 67      * 
 68      * @param title
 69      *            标题
 70      * @param content
 71      *            内容
 72      */
 73     public static void add(String title, String content,String remark) {
 74         try {
 75             Class.forName("com.mysql.jdbc.Driver");
 76             String url = "jdbc:mysql://localhost:3306/test";
 77             String user = "root";
 78             String password = "root";
 79             Connection conn = DriverManager.getConnection(url, user, password);
 80             Statement st = conn.createStatement();
 81             String sql = "insert into news values(null,'" + title + "','"
 82                     + content + "','"+ remark + "')";
 83             int row = st.executeUpdate(sql);
 84             System.out.println(row > 0 ? "添加成功" : "添加失败");
 85         } catch (Exception e) {
 86             e.printStackTrace();
 87         }
 88     }
 89 
 90     /**
 91      * 定义查询全部方法
 92      */
 93     public static void reads() {
 94         try {
 95             Class.forName("com.mysql.jdbc.Driver");
 96             String url = "jdbc:mysql://localhost:3306/test";
 97             String user = "root";
 98             String password = "root";
 99             Connection conn = DriverManager.getConnection(url, user, password);
100             Statement st = conn.createStatement();
101             String sql = "select * from news";
102             ResultSet list = st.executeQuery(sql);
103             if (list != null) {
104                 while (list.next()) {
105                     int id = list.getInt(1);
106                     String title = list.getString(2);
107                     String content = list.getString(3);
108                     String remark = list.getString(4);
109                     System.out.println(id + "t" + title + "t" + content
110                             + "t" + remark);
111                 }
112             }
113         } catch (Exception e) {
114             e.printStackTrace();
115         }
116     }
117 
118     /**
119      * 定义根据标题查询新闻的方法
120      * 
121      * @param title1
122      *            新闻标题
123      */
124     public static void read(String title1) {
125         try {
126             Class.forName("com.mysql.jdbc.Driver");
127             String url = "jdbc:mysql://localhost/test";
128             String user = "root";
129             String password = "root";
130             Connection conn = DriverManager.getConnection(url, user, password);
131             Statement st = conn.createStatement();
132             String sql = "select * from news where title='" + title1 + "'";
133             ResultSet row = st.executeQuery(sql);
134             if (row.next()) {
135                 int id = row.getInt(1);
136                 String title = row.getString(2);
137                 String content = row.getString(3);
138                 String remark = row.getString(4);
139                 System.out.println(id + "t" + title + "t" + content + "t"
140                         + remark);
141             }
142         } catch (Exception e) {
143             e.printStackTrace();
144         }
145     }
146 
147     /**
148      * 定义按标题删除新闻的方法
149      * 
150      * @param title
151      *            新闻方法
152      */
153     public static void delete(String title) {
154         try {
155             Class.forName("com.mysql.jdbc.Driver");
156             String url = "jdbc:mysql://localhost:3306/test";
157             String user = "root";
158             String password = "root";
159             Connection conn = DriverManager.getConnection(url, user, password);
160             Statement st = conn.createStatement();
161             String sql = "delete from news where title='" + title + "'";
162             int row = st.executeUpdate(sql);
163             System.out.println(row > 0 ? "删除成功" : "删除失败");
164         } catch (Exception e) {
165             e.printStackTrace();
166         }
167     }
168 
169     /**
170      * 定义根据标题修改新闻的方法
171      * 
172      * @param title
173      *            新闻标题
174      */
175     public static void update(String title) {
176 
177         try {
178             Class.forName("com.mysql.jdbc.Driver");
179             String url = "jdbc:mysql://localhost:3306/test";
180             String user = "root";
181             String password = "root";
182             Connection conn = DriverManager.getConnection(url, user, password);
183             Statement st = conn.createStatement();
184             String sql = "select * from news where title='" + title + "'";
185             ResultSet list = st.executeQuery(sql);
186             if (list.next()) {
187                 Scanner sca = new Scanner(System.in);
188                 System.out.println("请输入新的新闻标题:");
189                 String title4 = sca.next();
190                 System.out.println("请输入新闻内容:");
191                 String content = sca.next();
192                 System.out.println("请输入备注:");
193                 String remark = sca.next();
194                 
195                 String sql1 = "update news set title='" + title4
196                         + "',content='" + content + "',remark='" + remark + "' where title='"+title+"'";
197                 System.out.println(sql1);
198                 int u = st.executeUpdate(sql1);
199                 System.out.println(u > 0 ? "修改成功" : "修改失败");
200                 sca.close();
201             }
202         } catch (Exception e) {
203             e.printStackTrace();
204         }
205     }
206 }

好了,程序第二遍运转,程序会复制数据库,并把2017070101以此本子号写入到数据库中。

品味了四种百度近似题主的缓和格局都没意义(注!未有对程序做别的校勘卡塔 尔(英语:State of Qatar),最终不得已重启了一遍Computer,程序数据库能够平常访谈,原来以为没难点了, 然则前边又出新了壹回特别,不过程序日志呈现 现身至极后风度翩翩段时间 又有啥不可不奇怪访谈数据库了

 

- (void)initializeFXDB {
    NSString *path = [NSString stringWithFormat:@"%@fenxiao.db",[GlobalVariables getCustomResourcePath]];
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        [self copyFile2Documents:@"fenxiao.db"];
    }
}

网络同样特别音讯的有许多,可是实际和本人的情状是不雷同,有未有大佬蒙受过 求教

生机勃勃旦您的次序版本号未举行提高,仍为现阶段版本的话,其实就从不别的逻辑了。

借使小编的主次有数据库更新,那时候就须求进步自个儿先后中的数据库版本号:

指定到需要升级到的数据库版本
static int kDBVersion = 2018010101;

新的程序实施照旧去反省数据库,未有就复制目录中的数据库到沙盒中,并写入2018010101版本号;如若沙盒中有数据库文件,就抽出数据库的版本号,来超级大小。
若果开掘数指标本子号小于当前前后相继的本子,将数据库进级到当前版本,把程序的数据库版本号2018010101 写入数据库。

- (void)initializeFXDB {
    NSString *path = [NSString stringWithFormat:@"%@fenxiao.db",[GlobalVariables getCustomResourcePath]];
    if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
        [self copyFile2Documents:@"fenxiao.db"];
    }
    if ([self getDatabaseVersion] == 0) {
        [self setDatabaseVersion:kDBVersion];
    } else {
        //读取数据中的版本号,与程序中的VERSION_CODE 进行比较,如果相等,就什么都不做,如果小于,也不做,直接把数据版本号写入数据库。
        if ([self getDatabaseVersion] <= kDBVersion) {
            [self onUpgradeWithOldVesion:[self getDatabaseVersion] newVersion:kDBVersion];
            kDBVersion = [self getDatabaseVersion];
        } else {
            [self setDatabaseVersion:kDBVersion];
        }
    }
}

晋级的逻辑特别轻易,今后来写一下现实的晋级的不二秘技。

第生龙活虎看一下剧本文件的目录

图片 2

image.png

作者们须要读取全数的晋级脚本文件,依据名称进行排序,把文件名称转变到数字,大于数据版本号的提拔脚本都实践三遍。

//升级数据库版本方法
- (void)onUpgradeWithOldVesion:(int)oldVersion newVersion:(int)newVersion{
    [self executeMigrationsWithOldVesion:oldVersion newVersion:newVersion];
}

//顺序执行每个脚本文件
- (BOOL)executeMigrationsWithOldVesion:(int)oldVersion newVersion:(int)newVersion{
    BOOL migrationExecuted = false;
    @try {
        NSString *path = [[NSBundle mainBundle] bundlePath];
        NSFileManager *fileManger = [NSFileManager defaultManager];
        NSArray *files = [fileManger contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/Migrations",path] error:nil];

        for (NSString *file in files) {
            @try {
                int version = [[file replace:@".sql" withStr:@""] intValue];
                if (version > oldVersion && version <= newVersion) {
                    [self executeSqlScript:db file:file];
                    migrationExecuted = true;
                }
            } @catch (NSException *exception) {
                FXLog(@"%@",exception);
            }
        }
    } @catch (NSException *exception) {
        FXLog(@"%@",exception);
    }
    return migrationExecuted;
}

//逐行读取sql语句,拼接后运行每个脚本文件的sql语句
- (void)executeSqlScript:(FMDatabase *)db file:(NSString *)file{
    @try {
        NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Migrations/%@",file] ofType:nil];
        NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:path];
        NSData *data = [fh readDataToEndOfFile];
        NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

        NSArray *array = [string componentsSeparatedByString:@"n"];
        NSString *line = @"";
        NSString *sb = @"";
        for (int i = 0; i<array.count; i++) {
            line = array[i];
            if (line.length > 0) {
                if ([[line substringFromIndex:(line.length -1)] isEqualToString:@";"]) {
                    sb = [sb stringByAppendingString:line];
                } else {
                    sb = [sb stringByAppendingString:[NSString stringWithFormat:@"%@ ",line]];
                }
            }
        }
        //使用FMDB的话,此处需要使用executeStatements:方法,因为更新语句中可能存在重复语句,应当跳过去继续执行,弱否则语句不能继续执行下去。
        [[FXFMDB_DBTool dbTool].dbQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
            [db executeStatements:sb];
        }];
        //每次升级完成脚本后 设置数据库版本号
        [self setDatabaseVersion:[[file replace:@".sql" withStr:@""] intValue]];
    } @catch (NSException *exception) {
        FXLog(@"%@",exception);
        @throw exception;
    }
}

全体数据库升级历程就到位了,今后将上述进程中赢得数据库版本等艺术补充上,依据得以完结效果与利益自行百度也可。

//将数据库文件从资源库剪切到Documents目录,由于在沙盒里只有Documents目录是可读写的
- (NSString *)copyFile2Documents:(NSString*)fileName
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *destPath =[documentsDirectory stringByAppendingPathComponent:fileName];
//    NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Migrations/%@",fileName] ofType:nil];
    //  如果目标目录也就是(Documents)目录没有数据库文件的时候,才会复制一份,否则不复制
    if(![fileManager fileExistsAtPath:destPath]){
        NSString *sourcePath = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
        if (!sourcePath) {
            FXLog(@"sourcepath 为空!");
            @throw [NSException exceptionWithName:@"sourcepath 为空" reason:@"sourcepath 为空!" userInfo:nil];
            return @"";
        }
        [fileManager copyItemAtPath:sourcePath toPath:destPath error:&error];
    }
    return destPath;
}
//获取数据库版本号
- (int)getDatabaseVersion {
    __block int r = 0;
    NSArray<GXLinkedDictionary *> *arr = [[FXFMDB_DBTool dbTool] executeQuery:@"pragma user_version ; "];
    if (!arr || arr.count == 0) {
        return 0;
    }    
    GXLinkedDictionary *dict = arr[0];
    if (!dict || dict.count == 0) {
        return 0;
    }  
    [dict gxEnumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        r = (int)[obj longLongValue];
    }];
    return r;
}
//设置数据库版本号
- (void)setDatabaseVersion:(int)version {
    NSString *query = [NSString stringWithFormat:@"pragma user_version = %d", version];
    NSArray<GXLinkedDictionary *> *arr = [[FXFMDB_DBTool dbTool] executeQuery:query];
    if (arr.count) {
        FXLog(@"设置版本号为%d",version);
    }
}

本文由澳门威斯尼人平台登录发布于澳门威斯尼人平台登录,转载请注明出处:iOS数据库进级,SQL数据库间歇性至极

相关阅读