正在做一个系统,表结构与下边实现新闻功能的Demo基本相同,只不过Demo中相当于精简版
表结构如下:一、阅读人员表:Tbl_ReadersID        int  PK    ID值
NewsID    varchar    存储某一新闻条目的ID,用于与具体新闻表中的ID相连接
Reader    varchar    存储本条新闻应该由谁读取
NewsType  varchar    存储新闻的类型。不同类型的新闻在不同的数据库表中存储(请大家不要责怪我的数据库设计,因为这只是为了说明问题而做的Demo)
二、A新闻类型表:NewsTbl_AID        int  PK    ID值
NewsID    varchar    存储某一新闻条目的ID,用于与阅读人员表中的ID相连接
Title     varchar    A类型新闻的标题
三、B新闻类型表:NewsTbl_BID        int  PK    ID值
NewsID    varchar    存储某一新闻条目的ID,用于与阅读人员表中的ID相连接
Title     varchar    B类型新闻的标题
四、C、D、E ......新闻类型表(表的个数不定,由新闻类型的个数决定)
在阅读人员表Tbl_Readers的NewsType字段当中,存储了新闻的类型,如A、B等,并且加上前缀 NewTbl_ 就相当于存储该类型的新闻的数据库表的名称!!!
现在,我想按下边的格式取出某个读者所有的新闻列表:NewsID(新闻ID)、NewsType(新闻类型)、Title(新闻标题)
这也就意味着:
需要根据读者表Tbl_Readers的NewsType字段,加上前缀“NewTbl_”组成一个数据库表名,动态地决定去哪个新闻类型的表中取出Title字段的内容!!!
请问大家,这样的SQL语句我应该怎么写呢?拜托了~~谢谢大家

解决方案 »

  1.   

    我是这样写的:declare @theSQL varchar(1000)
    declare @thetable varchar(50)
    set @theSQL = 'SELECT A.NewsID,A.NewsType,B.Title from Tbl_Readers A inner join'
    set @thetable = ' NewsTbl_'+'A.NewsType'
    set @theSQL = @theSQL + @thetable + ' B on A.NewsID=B.NewsID where A.Reader like '%'+ @thereader +'%''select @theSQL
    提示的错误是:The data types varchar and varchar are incompatible in the modulo operator.
    拜托大家帮我看一下万分感谢了
      

  2.   

    觉得表设计没有问题(表分布),看看下面的代码能行不DECLARE @reader nvarchar(50)CREATE TABLE #ReaderNews -- 保存某一个用户阅读的新闻
    (
    ...
    ) DECLARE @newsId int, @newsType varchar(10), @sql varchar(1000)
    DECLARE @count intSELECT @count = COUNT(*) FROM #tmpReaderWHILE  @count > 0
    BEGIN
    SELECT TOP 1  @newsId = NewsId, @newsType = NewsType FROM #tmpReader
    SELECT @sql = 'INSERT INTO #ReaderNews SELECT * FROM NewsTbl_'+@newsType+' WHERE NewsId = '+@newsId
    EXEC(@sql) SET @count = @count - 1
    ENDSELECT * FROM #ReaderNewsDROP TABLE #ReaderNews
      

  3.   


    哦,我刚才的SQL中有一点小问题,改后可以执行成功了,但拼凑出来的SQL语句不正确!拼出来的SQL语句是:SELECT A.NewsID,A.NewsType,B.Title from Tbl_Readers A inner join NewsTbl_A.NewsType on A.NewsID=B.NewsID where A.Reader like '%username%'也就是说,A.NewsType在SQL语句中没有被解释,而被直接输出了!!!请问大家,我应该怎么拼接这个表示数据库表的字符串呢???
    谢谢大家了
      

  4.   


    哦,我刚才写错了输出的错误SQL语句是这样的:SELECT A.NewsID,A.NewsType,B.Title from Tbl_Readers A 
    inner join NewsTbl_A.NewsType B on A.NewsID=B.NewsID where A.Reader like '%username%'
      

  5.   

    你需要在存储中分析NewsType字段的值,假如“A,B” 
    通过字符操作,去拆分成A和B,查看CharIndex和SubString这两个sql函数。
    然后循环去做sql语句,并用Union来连接
      

  6.   


    哦,不是的,NewsType字段中只存储某一个新闻类型,如A或者B
      

  7.   

    to 哦,不是的,NewsType字段中只存储某一个新闻类型,如A或者Bsample code as follows:declare @theSQL varchar(1000)
    declare @thetable varchar(50)
    set @thetable = 'A,B' -- only for test --
    declare @nStartIndex Int
    declare @nIndex Int
    set @nStartIndex = 1
    set @nIndex = CHARINDEX( ',' , @thetable, nStartIndex )
    WHILE( @nIndex > 0 )
    BEGIN
         set @theSQL = @theSQL + ' UNION '
         set @theSQL = @theSQL + 'SELECT ID, NewsID, Title FROM NewsTbl_' + SUBSTRING( @thetable, @nStartIndex, @nIndex - 1 )
         set @nStartIndex = @nIndex + 1
         set @nIndex = CHARINDEX( ',' , @thetable, nStartIndex )
    ENDIF @nStartIndex <= LEN( @thetable )
    BEGIN
         set @theSQL = @theSQL + ' UNION '
         set @theSQL = @theSQL + 'SELECT ID, NewsID, Title FROM NewsTbl_' + SUBSTRING( @thetable, @nStartIndex, LEN( @thetable ) - @nStartIndex + 1 )
    ENDset @theSQL = SUBSTRING( @theSQL, 7, LEN( @theSQL ) - 6 ) -- remove the first " UNION " part
    EXEC( @theSQL )
      

  8.   


    TO:Knight94(愚翁)谢谢您的指点,不过set @thetable = 'A,B' -- only for test --我这个字段中只有A或者B,不需要拆分这个字符的操作啊而且我现在不清楚的是如何动态地取出这个字段的相应内容,拼接成一个表名,然后去这个表中取出对应条目的数据
    万分感谢您
      

  9.   


    相同的问题我在SQL版也发了一个,大家可以参考http://community.csdn.net/Expert/topic/5043/5043328.xml?temp=.729336请大家帮忙
      

  10.   

    to 我这个字段中只有A或者B,不需要拆分这个字符的操作啊那就更简单了declare @theSQL varchar(1000)
    declare @thetable varchar(50)
    set @thetable = 'A' -- only for test --set @theSQL = 'SELECT ID, NewsID, Title FROM NewsTbl_' + @thetable
    exec( @theSQL )
      

  11.   


    TO: Knight94(愚翁)我就是不知道怎么样从对应的table字段中取出新闻类型啊然后再去拼凑555555555555555
      

  12.   


    TO:vfp_system(菜鸟一个) 实在不好意思,您的方法我不是很理解太菜了~不好意思您能否根据我的测试表和测试数据帮我调试一下呢?非常着急~否则我就自己琢磨了~拜托您了万分感谢
      

  13.   

    我添了如下的测试数据:
    在Tbl_Readers表中:ID          NewsID             Reader          NewsType
    1             111              中国             A
    2             222              中国             B
    在NewsTbl_A表中:ID          NewsID               Title
    1            111                哈哈哈哈哈哈
    在NewsTbl_B表中:ID          NewsID               Title
    1            222                呵呵呵呵呵呵
    请大家帮我试一下我想要的结果是:ID          NewsType          TItle
    111           A           哈哈哈哈哈哈
    222           B           呵呵呵呵呵呵拜托大家了
      

  14.   

    Sample code as follows:
    declare @theSQL varchar(1000)
    declare @thetable varchar(50)
    Select @thetable=NewsType  From Tbl_Readers where Reader=@yourReaderParaset @theSQL = 'SELECT ID, NewsID, Title FROM NewsTbl_' + @thetable
    exec( @theSQL )
      

  15.   


    TO: Knight94(愚翁)您的方法没有拼凑出SQL语句啊
    55555555
      

  16.   

    如果是多条记录可以如下:
    declare @theSQL varchar(1000)
    declare @thetable varchar(50)DECLARE abc CURSOR FOR 
    Select NewsType From Tbl_Readers where Reader=@yourReaderParaSET @theSQL = ''
    OPEN abc
    FETCH NEXT FROM abc INTO @thetableWHILE @@FETCH_STATUS = 0
    BEGIN
        set @theSQL = @theSQL + ' UNION '
        set @theSQL = @theSQL + 'SELECT ID, NewsID, Title FROM NewsTbl_' + @thetable    FETCH NEXT FROM abc INTO @thetable
    ENDCLOSE abc
    DEALLOCATE abcset @theSQL = SUBSTRING( @theSQL, 7, LEN( @theSQL ) - 6 ) -- remove the first " UNION " part
    EXEC( @theSQL )
      

  17.   

    使用联合数据库服务器
    http://msdn2.microsoft.com/zh-cn/library/ms190381.aspx
      

  18.   


    TO Knight94(愚翁) 高手我太崇拜您了~~!!~~  ^o^我要拜师  555555555~~~成功了~~谢谢您  激动ing ~~~
      

  19.   


    TO Knight94(愚翁) 高手555555 我哭~~有个问题,我的ID, NewsID这两个字段都要从Tbl_Readers表(用户表)中取出来啊,而现在是从新闻表中取的能麻烦您再帮我看一下吗?万分感谢您
      

  20.   


    我 inner join 了一下,好像是可以了,,~正在调试呵呵
      

  21.   

    用游标逐语句的处理方式对性能的影响不知道怎么样?
    从前面的大概看了一下.你就是要区分出字段的值为A或者B,然后再处理.可以考虑用case语句吧.
    case a.newstype
    when 'A' then ...
    when 'B' then ...
    end
    另外,你的这句:
    set @thetable = ' NewsTbl_'+'A.NewsType'
    是不会得到a.newstype的值的,在这里它就是一个字符串,系统认为是两个字符串串联,结果就是newstbl_a.newstype了.如果你要想a.newstype为查出来的值,可以考虑这样:
    set @thetable='NewsTBl_'+(select a.newstype from ... where ...)这样的方式插入a.newstype字段里的值(而不是这几个字符)到你的查询语句里.
      

  22.   

    写一个视图就应好找了吧
    多表查询
    View 试一下
      

  23.   

    if exists(select 1 from sysobjects where type='u' and object_id('Tbl_Readers')=id)
    drop table Tbl_Readers
    if exists(select 1 from sysobjects where type='u' and object_id('NewsTbl_A')=id)
    drop table NewsTbl_A
    if exists(select 1 from sysobjects where type='u' and object_id('NewsTbl_B')=id)
    drop table NewsTbl_B
    gocreate table Tbl_Readers(ID int not null identity primary key,NewsID varchar(20) not null,Reader varchar(10) not null,NewsType varchar(10) not null)
    create table NewsTbl_A(ID int not null identity primary key,NewsID varchar(20) not null,Title varchar(100) not null)
    create table NewsTbl_B(ID int not null identity primary key,NewsID varchar(20) not null,Title varchar(100) not null)
    goinsert Tbl_Readers
    select '111','中國','A' union all
    select '222','中國','B' union all
    select '333','美國','B' insert NewsTbl_A
    select '111','哈哈哈哈哈哈'insert NewsTbl_B
    select '222','呵呵呵呵呵呵' union all
    select '333','呵呵呵呵呵呵' 
    goselect * from Tbl_Readers
    /*
    ID          NewsID             Reader          NewsType
    1             111              中?             A
    2             222              中?             B
    3             333              美國             B
    */select * from NewsTbl_A
    /*
    ID          NewsID               Title
    1            111                哈哈哈哈哈哈
    */select * from NewsTbl_B
    /*
    ID          NewsID               Title
    1            222                呵呵呵呵呵呵
    1            333                嘿嘿嘿嘿嘿嘿
    */
    declare @sql nvarchar(1000),@reader varchar(10)
    set @sql=''
    set @reader='中國'
    select @sql=@sql+'select A.NewsID,A.NewsType,B.Title from Tbl_Readers a  join  NewsTbl_'+NewsType+' b on A.NewsID=B.NewsID  and Reader='''+@reader+''' union all ' from Tbl_Readers where Reader=@reader group by NewsType
    if @sql<>''
    begin
      select @sql=left(@sql,len(@sql)-9)
      --select @sql
      exec(@sql)
    end
    /*
    ID          NewsType          TItle
    111           A           哈哈哈哈哈哈
    222           B           呵呵呵呵呵呵
    */--declare @sql nvarchar(1000),@reader varchar(10)
    set @sql=''
    set @reader='美國'
    select @sql=@sql+'select A.NewsID,A.NewsType,B.Title from Tbl_Readers a  join  NewsTbl_'+NewsType+' b on A.NewsID=B.NewsID  and Reader='''+@reader+''' union all ' from Tbl_Readers where Reader=@reader group by NewsType
    if @sql<>''
    begin
      select @sql=left(@sql,len(@sql)-9)
      --select @sql
      exec(@sql)
    end
    /*
    ID          NewsType          TItle
    333           B           呵呵呵呵呵呵
    */