1. mysql中怎樣查詢表中的儲存過程
假設A表有3個欄位,ID, DATA1,DATA2
簡單的話可以不使用存儲過程,比如:
select * form A where ID in (select ID from A where DATA1 between 0 and 100)
如果你的應用比較復雜,在嵌套中還有復雜的運算,存儲過程可以如下例子:
CREATE PROCEDURE test(in_start int,in_end int)
BEGIN
DECLARE ids TEXT;
select GROUP_CONCAT(ID) into ids from A where DATA1 between in_start and in_end;
select * from A where FIND_IN_SET(ID,ids) > 0;
END
註: in_start, in_end是DATA1的篩選范圍。 後面一個select直接返回一個表
直接用SQL和使用存儲過程各有利弊,存儲過程在你使用大量查詢及SQL運算的時候效率很高,而且存儲過程一旦寫入資料庫會被自動編譯運行速度比較快,而SQL是每次執行都需要被編譯一次的。但是存儲過程的調試比較麻煩,不像你使用編程語言和SQL的時候可以單步調試。而且如果沒有熟練掌握存儲過程的效率優化情況下,使用存儲過程可能比使用SQL更慢。
2. 用c語言實現線性表的順序存儲(創建,插入,刪除和查找)
//C++課程設計---學生成績管理系統
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <stdlib.h>
#include <windows.h>
typedef struct studentinfo //結構體定義
{
int num;//學號
char name[64];//姓名
int sex;//性別,1為男性,0為女性
float math;//數學
float english;//英語
float politic;//政治
float chinese;//語文
float total;//總成績
struct studentinfo *next;
}STUDENT;
#define FILENAME "D:\\1.txt"
//定義默認的資料庫文件
#define DELAYTIME 1500
//顯示信息,延時
void create_menu();
STUDENT * new_student();
STUDENT* create_linkbyfile(char *);
STUDENT *del_info(STUDENT *);
int save_info(char *,STUDENT *,int);
int find_infile_printf(char *);
int pri_whole_link(STUDENT *);
STUDENT* printf_sort(STUDENT *);
void free_link(STUDENT *);
void main() //主函數
{
create_menu();
}
STUDENT * reverse(STUDENT *head)
//功能:鏈表反轉順序
//參數:head鏈表頭結點指針
{
STUDENT *ptemp,*p1;
if(head==NULL)
{
return 0;
}
p1=head;//p1使之永遠指向排好序的第一個結點,初值為head,head使之永遠是已經排好序的最後一個結點
while(head->next!=NULL)//本次循環使ptemp排好序
{
ptemp=head->next;//ptemp指向未排好序的第一個結點
head->next=ptemp->next;//
ptemp->next=p1;//ptemp也排好序了,ptemp變成排好序的第一個結點了
p1=ptemp;//再次讓p1成為第一個排好序的結點
}
return p1;//頭結點為第一個結點
}
void create_menu()
//功能:輸出功能菜單,提供人-機介面
{
char menu_Num;
STUDENT *head=NULL;
char ch;
char file_name[256];
while(1)
{
system("cls");
cout<<"\t\t學生成績管理系統\n";
cout<<"##########################################\n";
cout<<"#\t\t 1.新增學生信息\t\t #\n";
cout<<"#\t\t 2.載入資料庫\t\t #\n";
cout<<"#\t\t 3.刪除學生信息\t\t #\n";
cout<<"#\t\t 4.保存學生信息\t\t #\n";
cout<<"#\t\t 5.資料庫查詢\t\t #\n";
cout<<"#\t\t 6.原序輸出\t\t #\n";
cout<<"#\t\t 7.排序輸出\t\t #\n";
cout<<"#\t\t 8.退出\t\t\t #\n";
cout<<"##########################################\n";
cout<<"請輸入操作編號:";
cin>>menu_Num;
switch (menu_Num)
{
case '1':
free_link(head);//釋放鏈表空間
head=new_student();//新增學生信息
break;
case '2':
free_link(head);//釋放鏈表空間
cout<<"請輸入要載入的資料庫文件的路徑"<<endl;
cin>>file_name;
head=create_linkbyfile(file_name);//讀取數據文件
if(head!=NULL)
{
cout<<"資料庫"<<file_name<<"已載入"<<endl;
Sleep(DELAYTIME);
}
break;
case '3':
del_info(head);//刪除學生信息
break;
case '4'://保存學生信息
if (head==NULL)
{
cout<<"請先生成學生信息"<<endl;
Sleep(DELAYTIME);
}
else
{
cout<<"想將學生信息保存到哪個資料庫文件?";
cin>>file_name;
cout<<"請選擇保存方式:0追加到文件末尾 1覆蓋文件\n";
cin>>menu_Num;
if(save_info(file_name,head,menu_Num-'0')==0)//0表示追加,1表示覆蓋
{
cout<<"信息保存失敗\n";
}
else
{
cout<<"數據已保存到"<<file_name<<endl;
Sleep(DELAYTIME);
}
}
break;
case '5':
find_infile_printf(FILENAME);//資料庫查詢
break;
case '6'://原序輸出信息
pri_whole_link(head);
cout<<"返回主菜單? Y/N\t";
do
{
cin>>ch;
}while(ch!='Y'&&ch!='y');
break;
case '7'://排序輸出信息
do
{
if((head=printf_sort(head))==NULL)
{
cout<<"資料庫未載入"<<endl;
Sleep(DELAYTIME);
break;
}
else
{
cout<<"選擇其他方式排序? Y/N\t";
cin>>ch;
}
}while(ch=='Y'||ch=='y');
break;
case '8':
free_link(head);//釋放鏈表空間
exit(0);
break;
default:
cout<<"輸入有誤!請重新輸入!"<<endl;
Sleep(DELAYTIME);
break;
}
}
}
STUDENT * new_student()
//功能:創建學生信息(通過鏈表)
//返回值:頭結點指針
{
STUDENT *pnew,*p,*head;
float *pfloat;
char ch;
head=NULL;
do
{
system("cls");
pnew=(STUDENT *)malloc(sizeof(STUDENT)*1);
cout<<"請輸入學生的學號(0表示取消): ";
cin>>pnew->num;
if(0>=pnew->num)
{
break;
}
cout<<"請輸入學生的姓名:";
cin>>pnew->name;
while(1)
{
cout<<"請輸入學生的性別:0/1\t";
cin>>pnew->sex;
if(pnew->sex&&pnew->sex-1)
{
cout<<"性別輸入錯誤,0表示女性,1表示男性,請重新輸入"<<endl;
}
else
{
break;
}
}
cout<<"請依次輸入學生的數學、英語、政治、語文成績:"<<endl;
for(pnew->total=0,pfloat=&pnew->math;pfloat<&pnew->math+4;)
{
cin>>*pfloat;
if(*pfloat<0||*pfloat>150)
{
cout<<"成績輸入錯誤,只能為0~150"<<endl;
}
else
{
pnew->total+=*pfloat;
pfloat++;
}
}
if(head==NULL)
{
head=pnew;
}
else
{
p->next=pnew;
}
p=pnew;
pnew->next=NULL;
cout<<"##########################該學生信息已生成#########################\n";
cout<<"建立另一個學生的信息? Y/N\t";
cin>>ch;
}while(ch=='Y'||ch=='y');
return head;
}
STUDENT* create_linkbyfile(char *filename)
//功能:讀取文件,創建鏈表
//參數:如果filename不為空,則打開該文件,如果filename為空,要求輸入文件位置
//創建的鏈表的所有結點的next全部修改,指向物理地址上的下一個結點
{
system("cls");
FILE *fp;
STUDENT *head,*ptemp,*pnew;
head=NULL;//初始化head為空
if(filename==NULL)//若filename為空,要求輸入文件絕對地址
{
char file_name[256];
cout<<"請輸入資料庫文件的路徑:"<<endl;
cin>>file_name;
if(NULL==(fp=fopen(file_name,"rb")))
{
cout<<"資料庫連接失敗\n";
return 0;
}
}
else
{
if(NULL==(fp=fopen(filename,"rb")))
{
cout<<"資料庫連接失敗\n";
return 0;
}
}
for(ptemp=NULL;;)
{
pnew=(STUDENT *)malloc(sizeof(STUDENT)*1);
if(fread(pnew,sizeof(STUDENT),1,fp)!=NULL)
{
if(ptemp!=NULL)
{
ptemp->next=pnew;
}
else
{
head=pnew;
}
ptemp=pnew;
}
else
{
if(ptemp!=NULL)
{
ptemp->next=NULL;
}
else
{
head=NULL;
}
free(pnew);
break;
}
}
fclose(fp);
return head;
}
STUDENT *del_info(STUDENT *head)
//根據學號,刪除鏈表的結點
{
system("cls");
STUDENT *p1,*p2;
int num;
if (head==NULL)
{
cout<<"資料庫未載入"<<endl;
Sleep(DELAYTIME);
return 0;
}
cout<<"請輸入要刪除學生的學號:";
cin>>num;
for(p1=head;p1!=NULL;)
{
if(p1->num==num)//找到
{
if(p1==head)//要刪除的結點是頭結點
{
head=p1->next;
}
else
{
p2->next=p1->next;
}
cout<<"成功刪除!!";
}
p2=p1;
p1=p1->next;
}
return head;
}
int save_info(char *filename,STUDENT *head,int flag)
//功能:將鏈表按Binary寫入文件末尾
//參數:
//1.filename文件名,絕對地址
//2.head指向鏈表的頭結點
//3.flag 0追加或1覆蓋數據
//返回值:失敗則返回0
{
system("cls");
FILE *fp;
STUDENT *p;
char openmethod[8];
if(flag==0)
{
strcpy(openmethod,"ab+");//追加
}
else
{
strcpy(openmethod,"w");//覆蓋
}
if(NULL==(fp=fopen(filename,openmethod)))//
{
cout<<"資料庫連接失敗"<<endl;
Sleep(DELAYTIME);
return 0;
}
else
{
for(p=head;p;p=p->next)
{
if((fwrite(p,sizeof(STUDENT),1,fp))==NULL)
{
cout<<"資料庫創建失敗"<<endl;
return 0;
}
}
}
fclose(fp);
return 1;
}
int find_infile_printf(char *filename)
//功能:根據學號和姓名來查詢某個學生
//參數:filename資料庫文件
//返回值:失敗返回0
//直接搜索文件,缺點是速度慢
//也可先根據文件創建鏈表,再搜索鏈表,缺點是如果文件較大,佔用內存多
{
system("cls");
FILE *fp;
STUDENT stu;
int num;
char stu_name[64];
char ch;
if(filename==NULL)
{
return 0;
}
do
{
memset(stu_name,0,sizeof(stu_name));
cout<<"查詢學號或查詢姓名? 1查詢學號 0查詢姓名";
//flag=1根據學號來查詢,flag=0根據姓名來查詢
cin>>num;
if(num==1)
{
cout<<"輸入要查詢的學號:";
cin>>num;
cout<<"正在為您查詢學號為"<<num<<"的學生……"<<endl;
}
else if(num==0)
{
cout<<"輸入要查詢的姓名:";
cin>>stu_name;
cout<<"正在為您查詢姓名為"<<stu_name<<"的學生……"<<endl;
}
else
{
cout<<"輸入有誤"<<endl;
return 0;
}
if(NULL==(fp=fopen(filename,"rw")))
{
cout<<"資料庫連接失敗\n";
return 0;
}
else
{
while(fread(&stu,sizeof(STUDENT),1,fp)!=NULL)
{
if(strcmp(stu.name,stu_name)==0||stu.num==num)
{
cout<<"學號\t姓名\t性別\t數學\t英語\t政治\t語文\t總成績\n";
//輸出該學生的所有信息
cout<<stu.num<<"\t"<<stu.name<<"\t"<<stu.sex<<"\t"<<stu.math<<"\t"<<stu.english<<"\t"<<stu.politic<<"\t"<<stu.chinese<<"\t"<<stu.total<<endl;
//不加break;可支持多個相同數據的索引
}
}
}
cout<<"##########################查詢完畢#########################\n";
cout<<"查詢另一個學生的信息? Y/N\t";
cin>>ch;
}while(ch=='Y'||ch=='y');
fclose(fp);
return 1;
}
int pri_whole_link(STUDENT *head)
//功能:顯示整條鏈表的學生信息
//參數:head 頭結點指針,如果head為空,返回空
{
system("cls");
STUDENT* p;
if (head==NULL)
{
cout<<"資料庫未載入"<<endl;
Sleep(DELAYTIME);
return 0;
}
cout<<"學號\t姓名\t性別\t數學\t英語\t政治\t語文\t總成績\n";
for(p=head;p;p=p->next)
{
cout<<p->num<<"\t"<<p->name<<"\t"<<p->sex<<"\t"<<p->math<<"\t"<<p->english<<"\t"<<p->politic<<"\t"<<p->chinese<<"\t"<<p->total<<endl;
}
return 1;
}
STUDENT* printf_sort(STUDENT *head)
//功能:根據學號|某科目成績|總成績對鏈表進行排序,然後輸出
//參數:head鏈表頭指針,如果head為空,返回空
//返回值:返回新的鏈表的頭結點指針
{
system("cls");
STUDENT *p1,*p2,*ptemp,*pfinished=NULL;
char num;
char flag;
if (head==NULL)
{
return 0;
}
cout<<"選擇排序依據 0.數學成績1.英語成績2.政治成績3.語文成績4.總成績\n";
while(1)
{
cin>>num;
if(num>'4'||num<'0')
{
cout<<"輸入有誤,請重新輸入 0~4"<<endl;
}
else
{
break;
}
}
cout<<"升序/降序輸出? 0.降序1.升序";
while(1)
{
cin>>flag;
if(flag>'1'||flag<'0')
{
cout<<"輸入有誤,請重新輸入 0~1"<<endl;
}
else
{
break;
}
}
for(p1=head;p1->next!=pfinished;)//對鏈表進行從大到小排序(這里用冒泡法)
//p1使之總是指向頭結點,pfinished使之總是指向已排序好的最前面的結點
//ptemp作為中介,保存p2的上一個結點
{
for(p2=p1;p2->next!=pfinished;)
{
if(*(&(p2->math)+num-'0')<*(&(p2->next->math)+num-'0'))//p2的值小於p2->next的值,交換 ptemp p2 p2->next
{
if(p2==p1)//頭結點要交換
{
p1=p2->next;
p2->next=p1->next;
p1->next=p2;
ptemp=p1;
}
else
{
ptemp->next=p2->next;
ptemp=p2->next;
p2->next=ptemp->next;
ptemp->next=p2;
}
}
else//不需要交換,則p2、ptemp前進1位
{
ptemp=p2;
p2=p2->next;
}
}
pfinished=p2;
}
if(flag=='1')
{
p1=reverse(p1);
}
pri_whole_link(p1);
cout<<"##########################信息顯示完畢#########################\n";
return p1;
}
void free_link(STUDENT *head)
//釋放鏈表空間,如果head,什麼都不做
{
STUDENT *p1,*p2;
for(p1=head;p1;p1=p2)
{
p2=p1->next;//先保存,否則
free(p1);//free後 p1->next數據丟失
}
}
3. 關於查詢數據表屬性的SQL代碼
CREATE TABLE
創建新表。
語法
CREATE TABLE
[ database_name.[ owner ] .| owner.] table_name
( { < column_definition >
| column_name AS computed_column_expression
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
)
[ ON { filegroup | DEFAULT } ]
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
< column_definition > ::= { column_name data_type }
[ COLLATE < collation_name > ]
[ [ DEFAULT constant_expression ]
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
]
[ ROWGUIDCOL]
[ < column_constraint > ] [ ...n ]
< column_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ NULL | NOT NULL ]
| [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = fillfactor ]
[ON {filegroup | DEFAULT} ] ]
]
| [ [ FOREIGN KEY ]
REFERENCES ref_table [ ( ref_column ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
]
| CHECK [ NOT FOR REPLICATION ]
( logical_expression )
}
< table_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
{ ( column [ ASC | DESC ] [ ,...n ] ) }
[ WITH FILLFACTOR = fillfactor ]
[ ON { filegroup | DEFAULT } ]
]
| FOREIGN KEY
[ ( column [ ,...n ] ) ]
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ]
( search_conditions )
}
參數
database_name
是要在其中創建表的資料庫名稱。database_name 必須是現有資料庫的名稱。如果不指定資料庫,database_name 默認為當前資料庫。當前連接的登錄必須在 database_name 所指定的資料庫中有關聯的現有用戶 ID,而該用戶 ID 必須具有創建表的許可權。
owner
是新表所有者的用戶 ID 名,owner 必須是 database_name 所指定的資料庫中的現有用戶 ID,owner 默認為與 database_name 所指定的資料庫中的當前連接相關聯的用戶 ID。如果 CREATE TABLE 語句由 sysadmin 固定伺服器角色成員或 database_name 所指定的資料庫中的 db_dbowner 或 db_ddladmin 固定資料庫角色成員執行,則 owner 可以指定與當前連接的登錄相關聯的用戶 ID 以外的其它用戶 ID。如果與執行 CREATE TABLE 語句的登錄相關聯的用戶 ID 僅具有創建表的許可權,則 owner 必須指定與當前登錄相關聯的用戶 ID。sysadmin 固定伺服器角色成員或別名為 dbo 用戶的登錄與用戶 ID dbo 相關聯;因此,由這些用戶創建的表的默認所有者為 dbo。不是由上述兩種角色的登錄創建的表所有者默認為與該登錄相關聯的用戶 ID。
table_name
是新表的名稱。表名必須符合標識符規則。資料庫中的 owner.table_name 組合必須唯一。table_name 最多可包含 128 個字元,但本地臨時表的表名(名稱前有一個編號符 #)最多隻能包含 116 個字元。
column_name
是表中的列名。列名必須符合標識符規則,並且在表內唯一。以 timestamp 數據類型創建的列可以省略 column_name。如果不指定 column_name,timestamp 列的名稱默認為 timestamp。
computed_column_expression
是定義計算列值的表達式。計算列是物理上並不存儲在表中的虛擬列。計算列由同一表中的其它列通過表達式計算得到。例如,計算列可以這樣定義:cost AS price * qty。表達式可以是非計算列的列名、常量、函數、變數,也可以是用一個或多個運算符連接的上述元素的任意組合。表達式不能為子查詢。
計算列可用於選擇列表、WHERE 子句、ORDER BY 子句或任何其它可使用常規表達式的位置,但下列情況除外:
計算列不能用作 DEFAULT 或 FOREIGN KEY 約束定義,也不能與 NOT NULL 約束定義一起使用。但是,如果計算列由具有確定性的表達式定義,並且索引列中允許計算結果的數據類型,則可將該列用作索引中的鍵列,或用作 PRIMARY KEY 或 UNIQUE 約束的一部分。
例如,如果表中含有整型列 a 和 b,則可以在計算列 a+b 上創建索引。但不能在計算列 a+DATEPART(dd, GETDATE()) 上創建索引,因為在以後的調用中,其值可能發生改變。
計算列不能作為 INSERT 或 UPDATE 語句的目標。
說明 表中計算列所使用的列值因行而異,因此每行的計算列值可能不同。
計算列的為空性是由 SQL Server 根據使用的表達式自動確定的。即使只有不可為空的列,大多數表達式的結果也認為是可為空的,因為可能的下溢或溢出也將生成 NULL 結果。使用 COLUMNPROPERTY 函數(AllowsNull 屬性)查看錶中任何計算列的為空性。通過指定 ISNULL(check_expression, constant),其中常量為替代任何 NULL 結果的非 NULL 值,可為空的表達式 expr 可以轉換為不可為空的表達式。
ON {filegroup | DEFAULT}
指定存儲表的文件組。如果指定 filegroup,則表將存儲在指定的文件組中。資料庫中必須存在該文件組。如果指定 DEFAULT,或者根本未指定 ON 參數,則表存儲在默認文件組中。
ON {filegroup | DEFAULT} 也可以在 PRIMARY KEY 約束或 UNIQUE 約束中指定。這些約束會創建索引。如果指定 filegroup,則索引將存儲在指定的文件組中。如果指定 DEFAULT,則索引將存儲在默認文件組中。如果約束中沒有指定文件組,則索引將與表存儲在同一文件組中。如果 PRIMARY KEY 約束或 UNIQUE 約束創建聚集索引,則表的數據頁將與索引存儲在同一文件組中。
說明 在 ON {filegroup | DEFAULT} 和 TEXTIMAGE_ON {filegroup | DEFAULT} 的上下文中,DEFAULT 並不是關鍵字。DEFAULT 是默認文件組的標識符並需對其進行定界,如 ON "DEFAULT"、ON [DEFAULT] 和 TEXTIMAGE_ON "DEFAULT" 或 TEXTIMAGE_ON [DEFAULT]。
TEXTIMAGE_ON
是表示 text、ntext 和 image 列存儲在指定文件組中的關鍵字。如果表中沒有 text、ntext 或 image 列,則不能使用 TEXTIMAGE ON。如果沒有指定 TEXTIMAGE_ON,則 text、ntext 和 image 列將與表存儲在同一文件組中。
data_type
指定列的數據類型。可以是系統數據類型或用戶定義數據類型。用戶定義數據類型必須先用 sp_addtype 創建,然後才能在表定義中使用。
在 CREATE TABLE 語句中,用戶定義數據類型的 NULL/NOT NULL 賦值可被替代。但長度標准不能更改;不能在 CREATE TABLE 語句中指定用戶定義數據類型的長度。
DEFAULT
如果在插入過程中未顯式提供值,則指定為列提供的值。DEFAULT 定義可適用於除定義為 timestamp 或帶 IDENTITY 屬性的列以外的任何列。除去表時,將刪除 DEFAULT 定義。只有常量值(如字元串)、系統函數(如 SYSTEM_USER())或 NULL 可用作默認值。為保持與 SQL Server 早期版本的兼容,可以給 DEFAULT 指派約束名。
constant_expression
是用作列的默認值的常量、NULL 或系統函數。
IDENTITY
表示新列是標識列。當向表中添加新行時,Microsoft® SQL Server™ 將為該標識列提供一個唯一的、遞增的值。標識列通常與 PRIMARY KEY 約束一起用作表的唯一行標識符。可以將 IDENTITY 屬性指派給 tinyint、smallint、int、bigint、decimal(p,0) 或 numeric(p,0) 列。對於每個表只能創建一個標識列。不能對標識列使用綁定默認值和 DEFAULT 約束。必須同時指定種子和增量,或者二者都不指定。如果二者都未指定,則取默認值 (1,1)。
seed
是裝入表的第一行所使用的值。
increment
是添加到前一行的標識值的增量值。
NOT FOR REPLICATION
表示當復制登錄(如 sqlrepl)向表中插入數據時,不強制 IDENTITY 屬性。復制的行必須保留發布資料庫中所賦予的鍵值;NOT FOR REPLICATION 子句確保不向復制進程所插入的行賦予新的標識值。其它登錄所插入的行仍然具有以通常的方式創建的新標識值。建議同時使用具有 NOT FOR REPLICATION 的 CHECK 約束,以確保賦予的標識值處於當前資料庫所需的范圍內。
ROWGUIDCOL
表示新列是行的全局唯一標識符列。對於每個表只能指派一個 uniqueidentifier 列作為 ROWGUIDCOL 列。ROWGUIDCOL 屬性只能指派給 uniqueidentifier 列。如果資料庫兼容級別小於或等於 65,則 ROWGUIDCOL 關鍵字無效。有關更多信息,請參見 sp_dbcmptlevel。
ROWGUIDCOL 屬性並不強制列中所存儲值的唯一性。該屬性也不會為插入到表中的新行自動生成值。若要為每列生成唯一值,那麼或者在 INSERT 語句中使用 NEWID 函數,或者將 NEWID 函數指定為該列的默認值。
collation_name
指定列的排序規則。排序規則名稱既可以是 Windows 排序規則名稱,也可以是 SQL 排序規則名稱。collation_name 僅適用於數據類型為 char、varchar、text、nchar、nvarchar 及 ntext 的列。如果沒有指定該參數,那麼如果列的數據類型是用戶定義的,則該列的排序規則就是用戶定義數據類型的排序規則,否則就是資料庫的默認排序規則。
有關 Windows 和 SQL 排序規則名稱的更多信息,請參見 COLLATE。
CONSTRAINT
是可選關鍵字,表示 PRIMARY KEY、NOT NULL、UNIQUE、FOREIGN KEY 或 CHECK 約束定義的開始。約束是特殊屬性,用於強制數據完整性並可以為表及其列創建索引。
constrain_name
是約束的名稱。約束名在資料庫內必須是唯一的。
NULL | NOT NULL
是確定列中是否允許空值的關鍵字。從嚴格意義上講,NULL 不是約束,但可以使用與指定 NOT NULL 同樣的方法指定。
PRIMARY KEY
是通過唯一索引對給定的一列或多列強制實體完整性的約束。對於每個表只能創建一個 PRIMARY KEY 約束。
UNIQUE
是通過唯一索引為給定的一列或多列提供實體完整性的約束。一個表可以有多個 UNIQUE 約束。
CLUSTERED | NONCLUSTERED
是表示為 PRIMARY KEY 或 UNIQUE 約束創建聚集或非聚集索引的關鍵字。PRIMARY KEY 約束默認為 CLUSTERED,UNIQUE 約束默認為 NONCLUSTERED。
在 CREATE TABLE 語句中只能為一個約束指定 CLUSTERED。如果在為 UNIQUE 約束指定 CLUSTERED 的同時又指定了 PRIMARY KEY 約束,則 PRIMARY KEY 將默認為 NONCLUSTERED。
[ WITH FILLFACTOR = fillfactor ]
指定 SQL Server 存儲索引數據時每個索引頁的充滿程度。用戶指定的 fillfactor 取值范圍從 1 到 100。如果沒有指定 fillfactor,則默認為 0。創建索引時,fillfactor 的值越低,不必分配新空間即可由新索引項使用的空間就越多。
FOREIGN KEY...REFERENCES
是為列中的數據提供引用完整性的約束。FOREIGN KEY 約束要求列中的每個值在被引用表中對應的被引用列中都存在。FOREIGN KEY 約束只能引用被引用表中為 PRIMARY KEY 或 UNIQUE 約束的列或被引用表中在 UNIQUE INDEX 內引用的列。
ref_table
是 FOREIGN KEY 約束所引用的表名。
(ref_column[,...n])
是 FOREIGN KEY 約束所引用的表中的一列或多列。
ON DELETE {CASCADE | NO ACTION}
指定當要創建的表中的行具有引用關系,並且從父表中刪除該行所引用的行時,要對該行採取的操作。默認設置為 NO ACTION。
如果指定 CASCADE,則從父表中刪除被引用行時,也將從引用表中刪除引用行。如果指定 NO ACTION,SQL Server 將產生一個錯誤並回滾父表中的行刪除操作。
例如,在 Northwind 資料庫中,Orders 表和 Customers 表之間有引用關系。Orders.CustomerID 外鍵引用 Customers.CustomerID 主鍵。
如果對 Customers 表的某行執行 DELETE 語句,並且為 Orders.CustomerID 指定 ON DELETE CASCADE 操作,則 SQL Server 將在 Orders 表中檢查是否有與被刪除的行相關的一行或多行。如果存在相關行,則 Orders 表中的相關行將隨 Customers 表中的被引用行一同刪除。
反之,如果指定 NO ACTION,若在 Orders 表中至少有一行引用 Customers 表中要刪除的行,則 SQL Server 將產生一個錯誤並回滾 Customers 表中的刪除操作。
ON UPDATE {CASCADE | NO ACTION}
指定當要創建的表中的行具有引用關系,並且在父表中更新該行所引用的行時,要對該行採取的操作。默認設置為 NO ACTION。
如果指定 CASCADE,則在父表中更新被引用行時,也將在引用表中更新引用行。如果指定 NO ACTION,SQL Server 將產生一個錯誤並回滾父表中的行更新操作。
例如,在 Northwind 資料庫中,Orders 表和 Customers 表之間有引用關系:Orders.CustomerID 外鍵引用 Customers.CustomerID 主鍵。
如果對 Customers 表的某行執行 UPDATE 語句,並且為 Orders.CustomerID 指定 ON UPDATE CASCADE 操作,則 SQL Server 將在 Orders 表中檢查是否有與被更新行相關的一行或多行。如果存在相關行,則 Orders 表中的相關行將隨 Customers 表中的被引用行一同更新。
反之,如果指定 NO ACTION,若在 Orders 表中至少有一行引用 Customers 行,則 SQL Server 將產生一個錯誤並回滾對 Customers 行的更新操作。
CHECK
是通過限制可輸入到一列或多列中的可能值強制域完整性的約束。
NOT FOR REPLICATION
是用於防止在復制所使用的分發過程中強制 CHECK 約束的關鍵字。當表是復制發布的訂戶時,請不要直接更新訂閱表,而要更新發布表,然後讓復制進程將數據分發回訂閱表。可以在訂閱表上定義 CHECK 約束,以防用戶修改訂閱表。但是如果不使用 NOT FOR REPLICATION 子句,CHECK 約束同樣會防止復制進程將修改從發布表分發給訂閱表。NOT FOR REPLICATION 子句表示對用戶的修改(而不是對復制進程)強加約束。
NOT FOR REPLICATION CHECK 約束適用於被更新記錄的前像和後像,以防在復制范圍中添加記錄或從復制范圍中刪除記錄。將檢查所有刪除和插入操作;如果操作在復制范圍內,則拒絕執行該操作。
如果對標識符列使用此約束,則當復制用戶更新標識列時,SQL Server 將允許不必重新計算表標識列的種子值。
logical_expression
是返回 TRUE 或 FALSE 的邏輯表達式。
column
是用括弧括起來的一列或多列,在表約束中表示這些列用在約束定義中。
[ASC | DESC]
指定加入到表約束中的一列或多列的排序次序。默認設置為 ASC。
n
是表示前面的項可重復 n 次的佔位符。
注釋
SQL Server 的每個資料庫最多可存儲 20 億個表,每個表可以有 1024 列。表的行數及總大小僅受可用存儲空間的限制。每行最多可以存儲 8,060 位元組。如果創建具有 varchar、nvarchar 或 varbinary 列的表,並且列的位元組總數超過 8,060 位元組,雖然仍可以創建此表,但會出現警告信息。如果試圖插入超過 8,060 位元組的行或對行進行更新以至位元組總數超過 8,060,將出現錯誤信息並且語句執行失敗。
包含 sql_variant 列的 CREATE TABLE 語句可以生成下列警告:
The total row size (xx) for table 'yy' exceeds the maximum number of bytes per row (8060). Rows that exceed the maximum number of bytes will not be added.
出現該警告是因為 sql_variant 的最大長度只能為 8016 位元組。當某個 sql_variant 列包含與最大長度接近的值時,它可以超過行的最大大小限制。
每個表最多可以有 249 個非聚集索引和一個聚集索引。其中包括所有為支持表中所定義的 PRIMARY KEY 和 UNIQUE 約束而生成的索引。
SQL Server 在列定義中並不強制以特定的順序指定 DEFAULT、IDENTITY、ROWGUIDCOL 或列約束。
臨時表
可以創建本地和全局臨時表。本地臨時表僅在當前會話中可見;全局臨時表在所有會話中都可見。
本地臨時表的名稱前面有一個編號符 (#table_name),而全局臨時表的名稱前面有兩個編號符 (##table_name)。
SQL 語句使用 CREATE TABLE 語句中為 table_name 指定的名稱引用臨時表:
CREATE TABLE #MyTempTable (cola INT PRIMARY KEY)
INSERT INTO #MyTempTable VALUES (1)
如果本地臨時表由存儲過程創建或由多個用戶同時執行的應用程序創建,則 SQL Server 必須能夠區分由不同用戶創建的表。為此,SQL Server 在內部為每個本地臨時表的表名追加一個數字後綴。存儲在 tempdb 資料庫的 sysobjects 表中的臨時表,其全名由 CREATE TABLE 語句中指定的表名和系統生成的數字後綴組成。為了允許追加後綴,為本地臨時表指定的表名 table_name 不能超過 116 個字元。
除非使用 DROP TABLE 語句顯式除去臨時表,否則臨時表將在退出其作用域時由系統自動除去:
當存儲過程完成時,將自動除去在存儲過程中創建的本地臨時表。由創建表的存儲過程執行的所有嵌套存儲過程都可以引用此表。但調用創建此表的存儲過程的進程無法引用此表。
所有其它本地臨時表在當前會話結束時自動除去。
全局臨時表在創建此表的會話結束且其它任務停止對其引用時自動除去。任務與表之間的關聯只在單個 Transact-SQL 語句的生存周期內保持。換言之,當創建全局臨時表的會話結束時,最後一條引用此表的 Transact-SQL 語句完成後,將自動除去此表。
在存儲過程或觸發器中創建的本地臨時表與在調用存儲過程或觸發器之前創建的同名臨時表不同。如果查詢引用臨時表,而同時有兩個同名的臨時表,則不定義針對哪個表解析該查詢。嵌套存儲過程同樣可以創建與調用它的存儲過程所創建的臨時表同名的臨時表。嵌套存儲過程中對表名的所有引用都被解釋為是針對該嵌套過程所創建的表,例如:
CREATE PROCEDURE Test2
AS
CREATE TABLE #t(x INT PRIMARY KEY)
INSERT INTO #t VALUES (2)
SELECT Test2Col = x FROM #t
GO
CREATE PROCEDURE Test1
AS
CREATE TABLE #t(x INT PRIMARY KEY)
INSERT INTO #t VALUES (1)
SELECT Test1Col = x FROM #t
EXEC Test2
GO
CREATE TABLE #t(x INT PRIMARY KEY)
INSERT INTO #t VALUES (99)
GO
EXEC Test1
GO
下面是結果集:
(1 row(s) affected)
Test1Col
-----------
1
(1 row(s) affected)
Test2Col
-----------
2
當創建本地或全局臨時表時,CREATE TABLE 語法支持除 FOREIGN KEY 約束以外的其它所有約束定義。如果在臨時表中指定 FOREIGN KEY 約束,該語句將返回警告信息,指出此約束已被忽略,表仍會創建,但不具有 FOREIGN KEY 約束。在 FOREIGN KEY 約束中不能引用臨時表。
考慮使用表變數而不使用臨時表。當需要在臨時表上顯式地創建索引時,或多個存儲過程或函數需要使用表值時,臨時表很有用。通常,表變數提供更有效的查詢處理。有關更多信息,請參見 table。
PRIMARY KEY 約束
一個表只能包含一個 PRIMARY KEY 約束。
由 PRIMARY KEY 約束生成的索引不能使表中的非聚集索引超過 249 個,聚集索引超過 1 個。
如果沒有在 PRIMARY KEY 約束中指定 CLUSTERED 或 NONCLUSTERED,並且沒有為 UNIQUE 約束指定聚集索引,則將對該 PRIMARY KEY 約束使用 CLUSTERED。
在 PRIMARY KEY 約束中定義的所有列都必須定義為 NOT NULL。如果沒有指定為空性,加入 PRIMARY KEY 約束的所有列的為空性都將設置為 NOT NULL。
UNIQUE 約束
如果 UNIQUE 約束中沒有指定 CLUSTERED 或 NONCLUSTERED,則默認為 NONCLUSTERED。
每個 UNIQUE 約束都生成一個索引。由 UNIQUE 約束生成的索引不能使表中的非聚集索引超過 249 個,聚集索引超過 1 個。
FOREIGN KEY 約束
如果在 FOREIGN KEY 約束的列中輸入非 NULL 值,則此值必須在被引用的列中存在,否則將返回違反外鍵約束的錯誤信息。
FOREIGN KEY 約束應用於前面所講的列,除非指定了源列。
FOREIGN KEY 約束僅能引用位於同一伺服器上的同一資料庫中的表。資料庫間的引用完整性必須通過觸發器實現。有關更多信息,請參見 CREATE TRIGGER。
FOREIGN KEY 可以引用同一表中的其它列(自引用)。
列級 FOREIGN KEY 約束的 REFERENCES 子句僅能列出一個引用列,且該列必須與定義約束的列具有相同的數據類型。
表級 FOREIGN KEY 約束的 REFERENCES 子句中引用列的數目必須與約束列列表中的列數相同。每個引用列的數據類型也必須與列表中相應列的數據類型相同。
如果 timestamp 類型的列是外鍵或被引用鍵的一部分,則不能指定 CASCADE。
可以在相互間具有引用關系的表上組合使用 CASCADE 和 NO ACTION。如果 SQL Server 遇到 NO ACTION,將終止執行語句並回滾相關的 CASCADE 操作。當 DELETE 語句導致 CASCADE 和 NO ACTION 組合操作時,在 SQL Server 檢查 NO ACTION 操作之前將執行所有 CASCADE 操作。
一個表最多可包含 253 個 FOREIGN KEY 約束。
對於臨時表不強制 FOREIGN KEY 約束。
每個表在其 FOREIGN KEY 約束中最多可以引用 253 個不同的表。
FOREIGN KEY 約束只能引用被引用表的 PRIMARY KEY 或 UNIQUE 約束中的列或被引用表上 UNIQUE INDEX 中的列。
DEFAULT 定義
每列只能有一個 DEFAULT 定義。
DEFAULT 定義可以包含常量值、函數、SQL-92 niladic 函數或 NULL。下表顯示 niladic 函數及其在執行 INSERT 語句時返回的默認值。 SQL-92 niladic 函數 返回的值
CURRENT_TIMESTAMP 當前日期和時間。
CURRENT_USER 執行插入操作的用戶名。
SESSION_USER 執行插入操作的用戶名。
SYSTEM_USER 執行插入操作的用戶名。
USER 執行插入操作的用戶名。
DEFAULT 定義中的 constant_expression 不能引用表中的其它列,也不能引用其它表、視圖或存儲過程。
不能在數據類型為 timestamp 的列或具有 IDENTITY 屬性的列上創建 DEFAULT 定義。
如果用戶定義數據類型綁定到默認對象,則不能在該用戶定義數據類型的列上創建 DEFAULT 定義。
CHECK 約束
列可以有任意多個 CHECK 約束,並且約束條件中可以包含用 AND 和 OR 組合起來的多個邏輯表達式。列上的多個 CHECK 約束按創建順序進行驗證。
搜索條件必須取值為布爾表達式,並且不能引用其它表。
列級 CHECK 約束只能引用被約束的列,表級 CHECK 約束只能引用同一表中的列。
當執行 INSERT 和 DELETE 語句時,CHECK CONSTRAINTS 和規則具有相同的數據驗證功能。
當列上存在規則和一個或多個 CHECK 約束時,將驗證所有限制。
其它約束信息
為約束創建的索引不能用 DROP INDEX 語句除去;必須用 ALTER TABLE 語句除去約束。可以用 DBCC DBREINDEX 語句重建為約束創建的並由其使用的索引。
約束的名稱必須符合標識符規則,但其名稱的首字元不能為 #。如果沒有提供 constraint_name,則使用系統生成的名稱。約束名將出現在所有與違反約束有關的錯誤信息中。
當 INSERT、UPDATE 或 DELETE 語句違反約束時,將終止執行該語句。但將繼續處理事務(如果此語句為顯式事務的組成部分)。可以通過檢查系統函數 @@ERROR,在事務定義中使用 ROLLBACK TRANSACTION 語句。
如果某個表具有 FOREIGN KEY 或 CHECK CONSTRAINTS 及觸發器,則將在觸發器執行前先檢查約束條件。
若要獲得關於表及其列的報表,請使用 sp_help 或 sp_helpconstraint。若要重命名表,請使用 sp_rename。若要獲得與表相關的視圖和存儲過程的報表,請使用 sp_depends。
通常情況下,為表和索引分配空間時,每次以一個擴展盤區為增量單位。當創建表或索引時,首先從混合擴展盤區為其分配頁,直到它具有足夠的頁填滿一個統一擴展盤區。當有足夠的頁填滿統一擴展盤區後,每當當前分配的擴展盤區填滿時,將再為其分配另一個擴展盤區。若要獲得關於由表分配和佔用的空間量的報表,請執行 sp_spaceused。
表定義中的為空性規則
列的為空性規則決定該列中是否允許以空值 (NULL) 作為其數據。NULL 不是零或空白:它表示沒有輸入任何內容,或提供了一個顯式 NULL 值,通常表示該值未知或不適用。
當用 CREATE TABLE 或 ALTER TABLE 語句創建或更改表時,資料庫或會話設置會影響且可能替代列定義中數據類型的為空性。建議始終將列顯式定義為非計算列的 NULL 或 NOT NULL,如果使用用戶定義數據類型,則建議允許該列使用此數據類型的默認為空性。
在沒有顯式指定時,列的為空性遵循以下規則:
如果該列以用戶定義數據類型定義:
SQL Server 使用在創建數據類型時指定的為空性。使用 sp_help 可獲得該數據類型的默認為空性。
如果該
4. 靜態查找表&動態查找表
靜態查找表:只查找,不改變集合內的數據元素。
一、順序查找( Linear search,又稱線性查找 )用逐一比較的辦法順序查找關鍵字。
1、順序查找時間復雜度:O(n)
2、順序查找平均查找長度 ASL=(n+1)/2
二、折半查找前提是順序存儲,記錄有序。
思想:與記錄中間值比較,如果比中間值小去左邊查,否則去右邊查找,直到找到為止,區域內沒記錄時查找失敗。
1、折半查找時間復雜度:O( )
2、折半查找平均查找長度 ASL=
動態查找表:既查找,又改變(增減)集合內的數據元素。
二叉排序樹滿足下列性質
1)若左子樹不為空,則左子樹上的所有結點的值(關鍵字)都小於根節點的值;
2)若右子樹不為空,則右子樹上的所有結點的值(關鍵字)都大於根節點的值;
3)左、右子樹都分別為二叉排序樹。
二叉排序樹的查找思想
1)首先將給定的K值與二叉排序樹的根節點的關鍵字進行比較:若相等,則查找成功;
2)若給定的K值小於二叉排序樹的根節點的關鍵字:繼續在該節點的左子樹上進行查找;
3)若給定的K值大於二叉排序樹的根節點的關鍵字:繼續在該節點的右子樹上進行查找。
二叉排序樹總結
1)查找過程與順序結構有序表中的折半查找相似,查找效率高;
2)中序遍歷此二叉樹,將會得到一個關鍵字的有序序列(即實現了排序運算);
3)如果查找不成功,能夠方便地將被查元素插入到二叉樹的葉子結點上,而且插入或刪除時只需修改指針而不需移動元素。
5. AVR匯編語言中,如何實現對RAM存儲單元的查表和對FLASH存儲單元的查表編程時有何區別
AVR單片機的CPU內核結構
位7-I:全局中斷使能位
當I位被置位時,表示CPU可以響應中斷請求,反之,則所有中斷被禁止。I位可以通過SEI和CLI指令來置位和清零,在中斷發生後,I位由硬體清除,並由RETI(中斷返回)指令置位。
位6-T:位拷貝存儲
位拷貝指令BLD和BST利用T作為目的或源地址。BST把寄存器的某一位拷貝到T,而BLD把T拷貝到寄存器的某一位。
位5-H:半進位標志半進位標志H表示算術操作發生了半進位,此標志對於BCD運算非常有用。
位4-S:符號位S=N⊕V,S為負數標志N與2的補碼溢出標志V的異或
位3-V:2的補碼溢出標志,支持2的補碼運算
位2-N:負數標志 表明算術或邏輯操作結果為負
位1-Z:零標志 表明算術或邏輯操作結果為零
位0-C:進位標志 表明算術或邏輯操作發生了進位
E.堆棧指針寄存器SP(Stack Point)
堆棧指針主要用來保存臨時數據、局部變數和中斷/子程序的返回地址。堆棧指針總是指向堆棧的頂部,AVR的堆棧是向下生長的,即新的數據推入堆棧時,堆棧指針的數值將減小。
處在I/O地址空間的&3E($005E)和$3D($005D)的兩個8位寄存器構成了AVR單片機的16位堆棧指針寄存器SP,分別為SPH,SPL。
堆棧指針指向數據SRAM堆棧區,必須指向高於0x60的地址空間,所以通常初始化時將SP的指針設在SRAM最高處。
使用PUSH指令將數據推入堆棧時指針減一;而子程序或中斷返回地址推入堆棧時指針將減二。
使用POP指令將數據彈出堆棧時,堆棧指針加一;而用RET或RETI指令從子程序或中斷返回時堆棧指針加二。
6. MCS-51單片機查表程序
16和7是查表指令時的PC與數據表格之間的位元組數
MOV A ,@R0 ;取R0指向的地址中的數據到A
ANL A,#0FH ;高四位清零
ADD A,#16 ;加16
MOVC A, @A+PC ;查表,表的首地址為絕對地址PC+A
MOVC A,@A+PC就需要1個位元組啊
查表指令距離表首地址的長度是位元組數
用DPTR的匯編程序:
ORG 0100H
MOV 30H,#12H
MOV 31H,#34H
MOV 32H,#56H
MOV 33H,#78H
LCALL SUBRTE
ORG 1000H
SUBRTE: MOV R0,#30H ; ;置地址指針R0初值
MOV R1,#40H ; ;置地址指針R1初值
MOV R2,#4 ; ;置位元組數
LOOP: MOV A,@R0 ; ;取16進制數
ANL A,#0FH ; ;屏蔽高4位
MOV DPTR,#TABLE ; ;
MOVC A,@A+DPTR ; ;查表低4位轉換為ASCⅡ碼
MOV @R1,A ; ;送結果
INC R1 ; ;修改指針
MOV A,@R0 ; ;從新取16進制數
SWAP A ; ;高4位與低4位互換
ANL A,#0FH ; ;取高4位
ADD A,#7
MOVC A,@A+PC ; ;查表高4位轉換為ASCⅡ碼
MOV @R1,A
INC R0
INC R1
DJNZ R2,LOOP
DEC R1
RET
TABLE: DB '012345678'
DB '9ABCDEF'
END
7. 數據結構實驗:線性表的順序表示和鏈式表示及插入、刪除、查找運算
這是我的第一次上機實驗課的內容來呢!
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
struct list //結點類型
{ int data;
struct list *next;
};
struct list *head;//聲明結點指針
int static length;//聲明表長變數
struct list *creat_n()//創建有n個元素的鏈表
{
struct list *q,*p,*head=NULL;
printf("\n輸入你所要創建的結點數: ");
scanf("%d",&length);
head=p=(list*)malloc(sizeof(list)); //創建一個新結點並用頭指針指向它
printf("輸入該結點的值: ");
scanf("%d", &p->data);
p->next=NULL;
for(int i=length-1;i>=1;i--)
{
q=p;
p=(list*)malloc(sizeof(list)); //創建新結點
printf("輸入該結點的值: ");
scanf("%d", &p->data);
q->next=p;
}
printf("輸入完畢\n\n");
p->next=NULL;
return head;
}
struct list * output()//輸出表長與結點值函數
{
struct list *p;
p=head;
printf("\n當前鏈表中存有的元素:\n");
while(p!=NULL)
{
printf("%d\n",p->data);
p=p->next;
}
printf("當前的表長是: %d\n\n",length);//輸出當前表長
return head;
}
void insert()//插入結點函數
{
struct list *k,*p,*q;
int x;
printf("請輸入你要在哪個結點值之前插入新結點: ");
scanf("%d",&x);
k=(list*)malloc(sizeof(list));//創建新結點
printf("請輸入新結點的值: ");
scanf("%d",&k->data);
k->next=NULL;
if(head==NULL)//若鏈表為空,則直接入鏈表
{
head=k;
length=length+1;
printf("插入成功\n\n");
}
else if(head->data==x)//在第一個結點前插入新結點
{
k->next=head;
head=k;
printf("插入成功\n\n");
length=length+1;
}
else
{
q=head;
p=head->next;
while((p != NULL) && (p->data != x))//找出值為X的結點的位置
{
q = p;
p = p->next;
}
if (p == NULL)
{
q->next=k;//在鏈表末插入新結點
printf("插入成功\n");
length=length+1;
}
else if(p->data == x)//在要求的X結點前插入新結點
{
k->next=p;
q->next=k;
printf("插入成功\n\n");
length=length+1;
}
}
output();
}
int delet()//刪除結點函數
{
struct list *q,*p;
int x,y;
printf("請輸入你所要刪除的結點值: ");
scanf("%d",&x);
if(head==NULL)//表空
{
printf("表空\n");
return 0 ;
}
else if(x==head->data)//第一個結點為刪除的結點
{
q=head;
head=head->next;
y=q->data;
free(q);
printf("刪除成功\n\n");
length=length-1;
output();
return(y);
}
else
{
q=head;
p=head->next;
while((p != NULL) && (p->data != x))//找出值為X的結點
{
q=p;
p=p->next;
}
if(p==NULL)
{
printf("沒有刪除對象\n");
}
if(x==p->data)//刪除值為X的結點
{
q->next=p->next;
y=p->data;
free(p);
printf("刪除成功\n\n");
length=length-1;
output();
return (y);
}
else
{
printf("表中沒有指定的結點\n");
output();
return 0;
}
}
return 0;
}
void find()
{
struct list *p;
int k,x,i=1;
char y,n;
LOOP:
p=head;
printf("請輸入你要查找的結點值: ");
scanf("%d",&x);
while(p->data!=x)
{
p=p->next;
i++;
}
printf("你所查找的結點是表中第 %d 個結點!\n\n",i);
printf("是否要繼續查找,請輸入y/n\n\n");
k=getch();
if(k=='y')
{
i=1;
goto LOOP;
}
else
return;
}
void main()
{
printf("計Y062 200502001052 李抱和\n\n");
int a;
LOOP:
printf(" *****************\n");
printf(" ** 1 創建鏈表 **\n");
printf(" ** 2 鏈表輸出 **\n");
printf(" ** 3 插入結點 **\n");
printf(" ** 4 刪除結點 **\n");
printf(" ** 5 查找結點 **\n");
printf(" *****************\n");
printf("\n請選擇: ");
scanf("%d",&a);
switch(a)
{
case 1 :
head=creat_n();
break;
case 2 :
output();
break;
case 3 :
insert();
break;
case 4 :
delet();
break;
case 5 :
find();
break;
}
goto LOOP;
}
8. 1. 用c語言編寫順序存儲結構下的順序查找法和鏈式存儲結構下的順序查找法。
是啊!而且非常重要它在筆試中佔30%!!!
這是我找到的一些資料:第一章 數據結構與演算法
1.1 演算法
1、演算法是指解題方案的准確而完整的描述。換句話說,演算法是對特定問題求解步驟的一種描述。
*:演算法不等於程序,也不等於計算方法。程序的編制不可能優於演算法的設計。
2、演算法的基本特徵
(1)可行性。針對實際問題而設計的演算法,執行後能夠得到滿意的結果。
(2)確定性。每一條指令的含義明確,無二義性。並且在任何條件下,演算法只有唯一的一條執行路徑,即相同的輸入只能得出相同的輸出。
(3)有窮性。演算法必須在有限的時間內完成。有兩重含義,一是演算法中的操作步驟為有限個,二是每個步驟都能在有限時間內完成。
(4)擁有足夠的情報。演算法中各種運算總是要施加到各個運算對象上,而這些運算對象又可能具有某種初始狀態,這就是演算法執行的起點或依據。因此,一個演算法執行的結果總是與輸入的初始數據有關,不同的輸入將會有不同的結果輸出。當輸入不夠或輸入錯誤時,演算法將無法執行或執行有錯。一般說來,當演算法擁有足夠的情報時,此演算法才是有效的;而當提供的情報不夠時,演算法可能無效。
*:綜上所述,所謂演算法,是一組嚴謹地定義運算順序的規則,並且每一個規則都是有效的,且是明確的,此順序將在有限的次數下終止。
3、演算法復雜度主要包括時間復雜度和空間復雜度。
(1)演算法時間復雜度是指執行演算法所需要的計算工作量,可以用執行演算法的過程中所需基本運算的執行次數來度量。
(2)演算法空間復雜度是指執行這個演算法所需要的內存空間。
1.2 數據結構的基本概念
1、數據結構是指相互有關聯的數據元素的集合。
2、數據結構主要研究和討論以下三個方面的問題:
(1)數據集合中各數據元素之間所固有的邏輯關系,即數據的邏輯結構。
數據的邏輯結構包含:1)表示數據元素的信息;2)表示各數據元素之間的前後件關系。
(2)在對數據進行處理時,各數據元素在計算機中的存儲關系,即數據的存儲結構。
數據的存儲結構有順序、鏈接、索引等。
1)順序存儲。它是把邏輯上相鄰的結點存儲在物理位置相鄰的存儲單元里,結點間的邏輯關系由存儲單元的鄰接關系來體現。由此得到的存儲表示稱為順序存儲結構。
2)鏈接存儲。它不要求邏輯上相鄰的結點在物理位置上亦相鄰,結點間的邏輯關系是由附加的指針欄位表示的。由此得到的存儲表示稱為鏈式存儲結構。
3)索引存儲:除建立存儲結點信息外,還建立附加的索引表來標識結點的地址。
*:數據的邏輯結構反映數據元素之間的邏輯關系,數據的存儲結構(也稱數據的物理結構)是數據的邏輯結構在計算機存儲空間中的存放形式。同一種邏輯結構的數據可以採用不同的存儲結構,但影響數據處理效率。
(3)對各種數據結構進行的運算。
3、數據結構的圖形表示
一個數據結構除了用二元關系表示外,還可以直觀地用圖形表示。在數據結構的圖形表示中,對於數據集合D中的每一個數據元素用中間標有元素值的方框表示,一般稱之為數據結點,並簡稱為結點;為了進一步表示各數據元素之間的前後件關系,對於關系R中的每一個二元組,用一條有向線段從前件結點指向後件結點。
4、數據結構分為兩大類型:線性結構和非線性結構。
(1)線性結構(非空的數據結構)條件:1)有且只有一個根結點;2)每一個結點最多有一個前件,也最多有一個後件。
*:常見的線性結構有線性表、棧、隊列和線性鏈表等。
(2)非線性結構:不滿足線性結構條件的數據結構。
*:常見的非線性結構有樹、二叉樹和圖等。
1.3 線性表及其順序存儲結構
1、線性表由一組數據元素構成,數據元素的位置只取決於自己的序號,元素之間的相對位置是線性的。線性表是由n(n≥0)個數據元素組成的一個有限序列,表中的每一個數據元素,除了第一個外,有且只有一個前件,除了最後一個外,有且只有一個後件。線性表中數據元素的個數稱為線性表的長度。線性表可以為空表。
*:線性表是一種存儲結構,它的存儲方式:順序和鏈式。
2、線性表的順序存儲結構具有兩個基本特點:(1)線性表中所有元素所佔的存儲空間是連續的;(2)線性表中各數據元素在存儲空間中是按邏輯順序依次存放的。
*:由此可以看出,在線性表的順序存儲結構中,其前後件兩個元素在存儲空間中是緊鄰的,且前件元素一定存儲在後件元素的前面,可以通過計算機直接確定第i個結點的存儲地址。
3、順序表的插入、刪除運算(學吧學吧獨家稿件)
(1)順序表的插入運算:在一般情況下,要在第i(1≤i≤n)個元素之前插入一個新元素時,首先要從最後一個(即第n個)元素開始,直到第i個元素之間共n-i+1個元素依次向後移動一個位置,移動結束後,第i個位置就被空出,然後將新元素插入到第i項。插入結束後,線性表的長度就增加了1。
*:順性表的插入運算時需要移動元素,在等概率情況下,平均需要移動n/2個元素。
(2)順序表的刪除運算:在一般情況下,要刪除第i(1≤i≤n)個元素時,則要從第i+1個元素開始,直到第n個元素之間共n-i個元素依次向前移動一個位置。刪除結束後,線性表的長度就減小了1。
*:進行順性表的刪除運算時也需要移動元素,在等概率情況下,平均需要移動(n-1)/2個元素。插入、刪除運算不方便。
1.4 棧和隊列
1、棧及其基本運算(學吧學吧獨家稿件)
棧是限定在一端進行插入與刪除運算的線性表。
在棧中,允許插入與刪除的一端稱為棧頂,不允許插入與刪除的另一端稱為棧底。棧頂元素總是最後被插入的元素,棧底元素總是最先被插入的元素。即棧是按照「先進後出」或「後進先出」的原則組織數據的。
棧具有記憶作用。
棧的基本運算:1)插入元素稱為入棧運算;2)刪除元素稱為退棧運算;3)讀棧頂元素是將棧頂元素賦給一個指定的變數,此時指針無變化。
棧的存儲方式和線性表類似,也有兩種,即順序棧和鏈式棧。
2、隊列及其基本運算
隊列是指允許在一端(隊尾)進入插入,而在另一端(隊頭)進行刪除的線性表。尾指針(Rear)指向隊尾元素,頭指針(front)指向排頭元素的前一個位置(隊頭)。
隊列是「先進先出」或「後進後出」的線性表。
隊列運算包括:1)入隊運算:從隊尾插入一個元素;2)退隊運算:從隊頭刪除一個元素。
循環隊列及其運算:所謂循環隊列,就是將隊列存儲空間的最後一個位置繞到第一個位置,形成邏輯上的環狀空間,供隊列循環使用。在循環隊列中,用隊尾指針rear指向隊列中的隊尾元素,用排頭指針front指向排頭元素的前一個位置,因此,從頭指針front指向的後一個位置直到隊尾指針rear指向的位置之間,所有的元素均為隊列中的元素。
*:循環隊列中元素的個數=rear-front。
1.5 線性鏈表(學吧學吧獨家稿件)
1、線性表順序存儲的缺點(學吧學吧獨家稿件):(1)插入或刪除的運算效率很低。在順序存儲的線性表中,插入或刪除數據元素時需要移動大量的數據元素;(2)線性表的順序存儲結構下,線性表的存儲空間不便於擴充;(3)線性表的順序存儲結構不便於對存儲空間的動態分配。
2、線性鏈表:線性表的鏈式存儲結構稱為線性鏈表,是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接來實現的。因此,在鏈式存儲方式中,每個結點由兩部分組成:一部分用於存放數據元素的值,稱為數據域;另一部分用於存放指針,稱為指針域,用於指向該結點的前一個或後一個結點(即前件或後件),如下圖所示:
線性鏈表分為單鏈表、雙向鏈表和循環鏈表三種類型。
在單鏈表中,每一個結點只有一個指針域,由這個指針只能找到其後件結點,而不能找到其前件結點。因此,在某些應用中,對於線性鏈表中的每個結點設置兩個指針,一個稱為左指針,指向其前件結點;另一個稱為右指針,指向其後件結點,這種鏈表稱為雙向鏈表,如下圖所示:
3、線性鏈表的基本運算
(1)在線性鏈表中包含指定元素的結點之前插入一個新元素。
*:在線性鏈表中插入元素時,不需要移動數據元素,只需要修改相關結點指針即可,也不會出現「上溢」現象(學吧學吧獨家稿件)。
(2)在線性鏈表中刪除包含指定元素的結點。
*:在線性鏈表中刪除元素時,也不需要移動數據元素,只需要修改相關結點指針即可。
(3)將兩個線性鏈表按要求合並成一個線性鏈表。
(4)將一個線性鏈表按要求進行分解。
(5)逆轉線性鏈表。
(6)復制線性鏈表。
(7)線性鏈表的排序。
(8)線性鏈表的查找。
*:線性鏈表不能隨機存取。
4、循環鏈表及其基本運算
在線性鏈表中,其插入與刪除的運算雖然比較方便,但還存在一個問題,在運算過程中對於空表和對第一個結點的處理必須單獨考慮,使空表與非空表的運算不統一。為了克服線性鏈表的這個缺點,可以採用另一種鏈接方式,即循環鏈表。
與前面所討論的線性鏈表相比,循環鏈表具有以下兩個特點:1)在鏈表中增加了一個表頭結點,其數據域為任意或者根據需要來設置,指針域指向線性表的第一個元素的結點,而循環鏈表的頭指針指向表頭結點;2)循環鏈表中最後一個結點的指針域不是空,而是指向表頭結點。即在循環鏈表中,所有結點的指針構成了一個環狀鏈。
下圖a是一個非空的循環鏈表,圖b是一個空的循環鏈表:
循環鏈表的優點主要體現在兩個方面:一是在循環鏈表中,只要指出表中任何一個結點的位置,就可以從它出發訪問到表中其他所有的結點,而線性單鏈表做不到這一點;二是由於在循環鏈表中設置了一個表頭結點,在任何情況下,循環鏈表中至少有一個結點存在,從而使空表與非空表的運算統一。
*:循環鏈表是在單鏈表的基礎上增加了一個表頭結點,其插入和刪除運算與單鏈表相同。但它可以從任一結點出發來訪問表中其他所有結點,並實現空表與非空表的運算的統一。
1.6 樹與二叉樹(學吧學吧獨家稿件)
1、樹的基本概念
樹是一種簡單的非線性結構。在樹這種數據結構中,所有數據元素之間的關系具有明顯的層次特性。
在樹結構中,每一個結點只有一個前件,稱為父結點。沒有前件的結點只有一個,稱為樹的根結點,簡稱樹的根。每一個結點可以有多個後件,稱為該結點的子結點。沒有後件的結點稱為葉子結點。
在樹結構中,一個結點所擁有的後件的個數稱為該結點的度,所有結點中最大的度稱為樹的度。樹的最大層次稱為樹的深度。
2、二叉樹及其基本性質
(1)什麼是二叉樹
二叉樹是一種很有用的非線性結構,它具有以下兩個特點:1)非空二叉樹只有一個根結點;2)每一個結點最多有兩棵子樹,且分別稱為該結點的左子樹與右子樹。
*:根據二叉樹的概念可知,二叉樹的度可以為0(葉結點)、1(只有一棵子樹)或2(有2棵子樹)。
(2)二叉樹的基本性質(學吧學吧獨家稿件)
性質1 在二叉樹的第k層上,最多有 個結點。
性質2 深度為m的二叉樹最多有個 個結點。
性質3 在任意一棵二叉樹中,度數為0的結點(即葉子結點)總比度為2的結點多一個。性質4 具有n個結點的二叉樹,其深度至少為 ,其中 表示取 的整數部分。
3、滿二叉樹與完全二叉樹
滿二叉樹:除最後一層外,每一層上的所有結點都有兩個子結點。
完全二叉樹:除最後一層外,每一層上的結點數均達到最大值;在最後一層上只缺少右邊的若干結點。
*:根據完全二叉樹的定義可得出:度為1的結點的個數為0或1。
下圖a表示的是滿二叉樹,下圖b表示的是完全二叉樹:
完全二叉樹還具有如下兩個特性:
性質5 具有n個結點的完全二叉樹深度為 。
性質6 設完全二叉樹共有n個結點,如果從根結點開始,按層序(每一層從左到右)用自然數1,2,…,n給結點進行編號,則對於編號為k(k=1,2,…,n)的結點有以下結論:
①若k=1,則該結點為根結點,它沒有父結點;若k>1,則該結點的父結點的編號為INT(k/2)。
②若2k≤n,則編號為k的左子結點編號為2k;否則該結點無左子結點(顯然也沒有右子結點)。
③若2k+1≤n,則編號為k的右子結點編號為2k+1;否則該結點無右子結點。
4、二叉樹的存儲結構
在計算機中,二叉樹通常採用鏈式存儲結構。
與線性鏈表類似,用於存儲二叉樹中各元素的存儲結點也由兩部分組成:數據域和指針域。但在二叉樹中,由於每一個元素可以有兩個後件(即兩個子結點),因此,用於存儲二叉樹的存儲結點的指針域有兩個:一個用於指向該結點的左子結點的存儲地址,稱為左指針域;另一個用於指向該結點的右子結點的存儲地址,稱為右指針域。
*:一般二叉樹通常採用鏈式存儲結構,對於滿二叉樹與完全二叉樹來說,可以按層序進行順序存儲。
5、二叉樹的遍歷(學吧學吧獨家稿件)
二叉樹的遍歷是指不重復地訪問二叉樹中的所有結點。二叉樹的遍歷可以分為以下三種:
(1)前序遍歷(DLR):若二叉樹為空,則結束返回。否則:首先訪問根結點,然後遍歷左子樹,最後遍歷右子樹;並且,在遍歷左右子樹時,仍然先訪問根結點,然後遍歷左子樹,最後遍歷右子樹。
(2)中序遍歷(LDR):若二叉樹為空,則結束返回。否則:首先遍歷左子樹,然後訪問根結點,最後遍歷右子樹;並且,在遍歷左、右子樹時,仍然先遍歷左子樹,然後訪問根結點,最後遍歷右子樹。
(3)後序遍歷(LRD):若二叉樹為空,則結束返回。否則:首先遍歷左子樹,然後遍歷右子樹,最後訪問根結點,並且,在遍歷左、右子樹時,仍然先遍歷左子樹,然後遍歷右子樹,最後訪問根結點。
1.7 查找技術(學吧學吧獨家稿件)
查找:根據給定的某個值,在查找表中確定一個其關鍵字等於給定值的數據元素。
查找結果:(查找成功:找到;查找不成功:沒找到。)
平均查找長度:查找過程中關鍵字和給定值比較的平均次數。
1、順序查找
基本思想:從表中的第一個元素開始,將給定的值與表中逐個元素的關鍵字進行比較,直到兩者相符,查到所要找的元素為止。否則就是表中沒有要找的元素,查找不成功。
在平均情況下,利用順序查找法在線性表中查找一個元素,大約要與線性表中一半的元素進行比較,最壞情況下需要比較n次。
順序查找一個具有n個元素的線性表,其平均復雜度為O(n)。
下列兩種情況下只能採用順序查找:
1)如果線性表是無序表(即表中的元素是無序的),則不管是順序存儲結構還是鏈式存儲結構,都只能用順序查找。
2)即使是有序線性表,如果採用鏈式存儲結構,也只能用順序查找。
2、二分法查找
思想:先確定待查找記錄所在的范圍,然後逐步縮小范圍,直到找到或確認找不到該記錄為止。
前提:必須在具有順序存儲結構的有序表中進行。
查找過程:
1)若中間項(中間項mid=(n-1)/2,mid的值四捨五入取整)的值等於x,則說明已查到;
2)若x小於中間項的值,則在線性表的前半部分查找;
3)若x大於中間項的值,則在線性表的後半部分查找。
特點:比順序查找方法效率高。最壞的情況下,需要比較log2n次。
*:二分法查找只適用於順序存儲的線性表,且表中元素必須按關鍵字有序(升序)排列。對於無序線性表和線性表的鏈式存儲結構只能用順序查找。在長度為n的有序線性表中進行二分法查找,其時間復雜度為O(log2n)。
1.8 排序技術(學吧學吧獨家稿件)
排序是指將一個無序序列整理成按值非遞減順序排列的有序序列,即是將無序的記錄序列調整為有序記錄序列的一種操作。
1、交換類排序法(方法:冒泡排序,快速排序)。
2、插入類排序法(方法:簡單插入排序,希爾排序)。
3、選擇類排序法(方法:簡單選擇排序,堆排序)。
總結:各種排序法比較:
本章應考點撥:本章內容在筆試中會出現5-6個題目,是公共基礎知識部分出題量比較多的一章,所佔分值也比較大,約10分。
9. oracle中怎麼查找指定表所涉及的存儲過程 急,在線等
在PLSQL 中我用select * from user_tables可以查詢到當前用戶下的存在的表,怎樣查詢到這個資料庫所有用戶下存在的表名
查詢資料庫中所有的表:
select * from all_tables;
查詢當前DBA用戶所能看到的表:
select * from dba_tables;
查詢oracle中所有的表的列名:
select * from all_tab_columns ct where ct.TABLE_NAME='sys_notify_task' ;
select * from all_tab_cols s where s.owner='stock';
10. 數據結構 c語言版 ——順序表的查找、插入與刪除
#include<stdio.h>
#include<stdlib.h>
#define N 10 //順序表的最大容量
int length=0; //順序表的當前元素個數
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100//線性表存儲的空間初始化分配量
#define LISTINCREAMENT 10 //線性表存儲空間的分配增量
typedef struct LNode//線性單鏈表存儲結構
{
int data;
struct LNode *next;
}LNode,*LinkList;
int CreatList_L(LinkList&L)//創建一個線性鏈表
{
L=(LinkList)malloc(sizeof(LNode));//分配一個空間給鏈表,作為頭結點
if(!L) exit(OVERFLOW);
L->next=NULL;
return OK;
}
int DestroyList_L(LinkList &L)//銷毀鏈表
{
if(L) free(L);
return OK;
}
int ListInsert_L(LinkList&L,int i,int e)//再練表的第i個元素前插入一個元素e
{
LinkList p=L;//p指針定位於i-1
LNode *s;
int j=0;
while(p&&j<i-1) {p=p->next;j++;}//定位
if(!p||j>i-1) return ERROR;//如果i<1或大於鏈表元素個數+1
s=(LNode*)malloc(sizeof(LNode));
if(!s) exit(OVERFLOW);
s->data=e; //完成插入操作
s->next=p->next;
p->next=s;
return OK;
}
int ListDelet_L(LinkList&L,int i,int&e)//刪除鏈表L中的第i個元素,並返回給e;
{
LinkList p=L;
LNode* q;
int j=0;
while(!p&&j<i-1) {p=p->next;j++;}//p指針定位於i-1;
if(!p->next||j>i-1) return ERROR;
e=p->next->data; //完成刪除操作
q=p->next;
p->next=p->next->next;
free(q);
return OK;
}
int ListTraverse_L(LinkList L,int n)//鏈表的遍歷
{
int i=0;
if(!L)return ERROR;
L=L->next;
while(L)
{
if(L->data==n)return i;
L=L->next;
i++;
}
return FALSE;
}
int InverseSingleList_L(LinkList &L)
{
if(!L->next||!L->next->next)//如果鏈表少於2個Node那麼鏈表不需要改變順序
return OK;
LNode *p,*q;
p=L->next; //第一次因為p是最後一個連接所以把p->next設為空
q=p->next;
p->next=NULL;
p=q;
while(p)
{
q=p->next; //用q去保留p後面一個Node;
p->next=L->next;
L->next=p;
p=q;
}
return OK;
}
int main()
{
int List[N];
LinkList L;
int ch,exit='N';
do
{
system("CLS");
printf("\t\t********************************************\n");
printf("\t\t* 1.創建一個順序表 .........(1) *\n");
printf("\t\t* 2.在順序表中查找元表.........(2) *\n");
printf("\t\t* 3.在順序表中插入元表.........(3) *\n");
printf("\t\t* 4.在順序表中刪除元表.........(4) *\n");
printf("\t\t* 5.退出 .........(5) *\n");
printf("\t\t********************************************\n");
printf("\n請選擇操作代碼:");
ch=getchar();
switch(ch)
{
case '1':
printf("\n請輸入十個元素");
CreatList_L(L);
for(length=0;length<N;length++)
{
scanf("%d",&List[length]);
getchar();
ListInsert_L(L,length+1,List[length]);
}
printf("\n創建成功!");
getchar();
break;
case '2':
scanf("%d",&List[0]);
if(ListTraverse_L(L,List[0]))printf("該元素存在該年表的第%d個位置",ListTraverse_L(L,List[0]));
else printf("不存在該元素");
getchar();
break;
case '3':
scanf("%d%d",&length,&List[0]);
ListInsert_L(L,length,List[0]);
system("pause");
break;
case '4':
scanf("%d",&length);
ListDelet_L(L,length,List[0]);
system("pause");
break;
case '5':
printf("\n您是否真的要退出程序(Y/N):");
getchar();
exit=getchar();
break;
default:
getchar();
printf("\n無效輸入,請重新選擇...:");
getchar();
break;
}
}while(exit!='y'&&exit!='Y');
}