背景

一个15G左右的sql文件,无法直接倒入到数据库中

sql分割

在linux环境下,使用awk脚本分割,每个文件5000000行,分割完成后会得到多个文件,除了第一个001的文件包含sql头部信息,其他文件均无sql头部信息,所以还需要为每个文件添加sql头部信息,才能正常倒入到数据库

awk脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash

# 定义每个文件的最大行数
LINES_PER_FILE=5000000

# 检查输入文件是否提供
if [ -z "$1" ]; then
echo "Usage: $0 <input_sql_file>"
exit 1
fi

INPUT_FILE="$1"
FILENAME=$(basename "$INPUT_FILE")
DIRNAME=$(dirname "$INPUT_FILE")
OUTPUT_PREFIX="${DIRNAME}/${FILENAME%.*}_part" # 例如:my_sql_file_part

echo "Splitting '$INPUT_FILE' into files with a maximum of $LINES_PER_FILE lines each."

# 使用 awk 进行分割
awk -v lines_per_file="$LINES_PER_FILE" \
-v output_prefix="$OUTPUT_PREFIX" \
'{
# 计算当前行所属的文件编号
file_num = int((NR - 1) / lines_per_file) + 1;
# 格式化文件名,确保有前导零,例如 _part_001, _part_010, _part_100
output_file = sprintf("%s_%03d.sql", output_prefix, file_num);
# 将当前行写入对应文件
print > output_file;
}' "$INPUT_FILE"

echo "Splitting complete."

给文件添加头部信息

通过 head -n 50 命令,查看原文件的头部信息,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
USE [BigData]
GO
/****** Object: Table [dbo].[Big_1_shun] Script Date: 03/09/2020 10:44:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Big_1_shun](
[name] [varchar](40) NULL,
[phone] [varchar](15) NULL,
[province] [varchar](30) NULL,
[city] [varchar](30) NULL,
[dist] [varchar](40) NULL,
[addr] [varchar](200) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO

将以上头部信息保存在文件中,命名为sql_header.sql

添加头部信息脚本

通过执行以下脚本,为分割后的文件,添加头部信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/bash

# 定义头部信息文件的路径
HEADER_FILE="sql_header.sql"

# 定义你的分割文件所在的目录(如果和脚本在同一目录,可以省略路径)
# 如果你的文件在 /home/user/my_sql_parts/ 目录下,就设置为这个路径
SQL_FILES_DIR="./"

# 定义分割文件的命名模式 (例如:*_part_*.sql)
# 如果你的文件是 scriptutf8_part_001.sql, scriptutf8_part_002.sql 等,这个模式就对
SQL_FILE_PATTERN="*_part_*.sql"

# 检查头部文件是否存在
if [ ! -f "$HEADER_FILE" ]; then
echo "Error: Header file '$HEADER_FILE' not found. Please create it first."
exit 1
fi

echo "Adding header from '$HEADER_FILE' to all files matching '$SQL_FILES_DIR/$SQL_FILE_PATTERN'..."

# 遍历所有匹配的文件
for sql_file in "$SQL_FILES_DIR"/$SQL_FILE_PATTERN; do
if [ -f "$sql_file" ]; then # 确保是文件
echo "Processing: $sql_file"

# 将头部文件内容插入到目标文件的开头
# 使用cat命令拼接,并将结果重定向到临时文件,然后替换原文件
cat "$HEADER_FILE" "$sql_file" > "${sql_file}.tmp" && mv "${sql_file}.tmp" "$sql_file"

# 或者如果你更喜欢sed的in-place编辑,但它在某些系统上行为不同
# sed -i "1s/^/$(cat "$HEADER_FILE")\n/" "$sql_file"
# 注意:sed插入多行可能有点复杂,cat拼接通常更可靠和通用

else
echo "Warning: No files found matching '$SQL_FILES_DIR/$SQL_FILE_PATTERN' or '$sql_file' is not a regular file."
fi
done

echo "Header addition complete for all matching files."

操作完成后,就可以将数据倒入到sql server服务器数据库了