V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
KagamineLenKai2
V2EX  ›  MySQL

看到别人写 SQL 会在 where 后面写 1=1,是什么意思?

  •  
  •   KagamineLenKai2 · 2016-09-02 11:46:49 +08:00 · 21966 次点击
    这是一个创建于 3000 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SELECT * FROM operation_log o
    where 1=1
    and o.operation_time>='2016/6/1'
    and o.operation_time<'2016/7/28'
    这个 1=1 好像写不写都没关系哦?

    77 条回复    2016-09-05 18:58:44 +08:00
    yatesun
        1
    yatesun  
       2016-09-02 11:51:38 +08:00
    感觉主要是有些人喜欢拼接 sql ,这样能保证一定有个 where 字段,其实没什么意义。
    solaya
        2
    solaya  
       2016-09-02 11:53:38 +08:00
    就是为了加 and   拼接 sql 语句
    tabris17
        3
    tabris17  
       2016-09-02 11:55:49 +08:00
    为了拼接方便
    php230
        4
    php230  
       2016-09-02 11:57:21 +08:00
    拼接条件
    wyntergreg
        5
    wyntergreg  
       2016-09-02 12:01:12 +08:00   ❤️ 3
    楼上说的都对,跟 2=2 没什么区别,为了语法凑字数用的。如果不加这个 1=1 ,那么在拼 sql 的时候你要判断拼上去的第一个条件是不带 and 的,然而很多查询都是多条件组合查询的,你并不知道哪一个条件会拼在第一个上,所以干脆把第一个条件写成 sql 认为的"true",其他所有条件都是 and
    est
        6
    est  
       2016-09-02 12:03:08 +08:00   ❤️ 1
    知道真像的我。。。。😂

    没有 ORM 你么肿么活下来的。。。
    KagamineLenKai2
        7
    KagamineLenKai2  
    OP
       2016-09-02 12:09:45 +08:00   ❤️ 1
    抱歉刚接触 SQL ,你们说的没听懂……
    SELECT * FROM operation_log o
    where o.operation_time>='2016/6/1'
    and o.operation_time<'2016/7/28'
    这样写不也可以么?
    tmkook
        8
    tmkook  
       2016-09-02 12:13:14 +08:00   ❤️ 1
    $sql = "SELECT * FROm table WHERE 1=1":
    if($_GET['filed1']){
    $sql .= "AND filed1=1":
    }
    if($_GET['filed2']){
    $sql .= "AND filed2=2":
    }

    哈哈哈,曾经也是玩的很溜的
    caixiexin
        9
    caixiexin  
       2016-09-02 12:13:49 +08:00 via Android   ❤️ 2
    一般是这个方法里的 SQL 是根据入参动态生成的,比如有多个条件,这些条件又不是必填,那就在 where 1=1 ,后面接多个 and xxx 就行了。不然要是哪天 where 条件的参数变了,还要改 where xxx 。
    where 1=1 MySQL 查询分析器会自动优化,没有性能问题。
    Clarencep
        10
    Clarencep  
       2016-09-02 12:20:25 +08:00
    都是不会用 implode 的程序猿惹的祸
    ijustdo
        11
    ijustdo  
       2016-09-02 12:33:04 +08:00
    我看到都蛋疼 不说 直接上代码

    $conditions_str = implode(',', array_map(function($x){return sprintf('%s=:%s', $x, $x);}, array_keys($conditions)));
    if (!empty($conditions_str)){
    $conditions_str = " where {$conditions_str} ";
    }
    liqingcan
        12
    liqingcan  
       2016-09-02 12:35:40 +08:00   ❤️ 3
    有人发现了吗。在座的发代码出来的全都是 phper
    ijustdo
        13
    ijustdo  
       2016-09-02 12:41:24 +08:00
    呵呵 我不是咧 主营不是拍好 p 我只是看到上面都用 php 举例子 也就去翻了下以前的代码
    flydogs
        14
    flydogs  
       2016-09-02 13:19:49 +08:00
    1.不需要判断有没有条件
    2.不需要判断第一个条件还是第 N 个条件
    Infernalzero
        15
    Infernalzero  
       2016-09-02 13:23:37 +08:00
    @liqingcan 因为 java 的话用 mybatis 会自动帮你去掉多余的 and 所以根本不需要写 1=1 去拼接
    ebony0319
        16
    ebony0319  
       2016-09-02 13:34:29 +08:00 via Android
    这个是为了保持语法正确,比如有很多文本框 txt ,但是不能保证用户都输入数值。比如
    temp="select * from a where 1=1"
    if txt<>"" then
    temp=temp+"and id=" +txt

    手机写的,大概就是这个意思。
    yueyoum
        17
    yueyoum  
       2016-09-02 14:38:35 +08:00
    上面说 为了拼接 SQL 方便的, 其实是 那个程序员太懒,太 LOW 而已。

    1 , 为何不用 ORM ?
    2 , 就算不用 ORM , 拼接那些 SQL 很难?
    jydeng
        18
    jydeng  
       2016-09-02 14:49:50 +08:00
    因为懒的判断。
    mringg
        19
    mringg  
       2016-09-02 14:59:43 +08:00
    我也挺喜欢用这种拼接 sql 的方式 进行查询,非常方便,但是得注意安全性问题
    linescape
        20
    linescape  
       2016-09-02 15:17:12 +08:00
    @yueyoum
    1.ORM 底层也是拼 sql
    2.复杂的多表联查, ORM 就蛋疼了
    ytmsdy
        21
    ytmsdy  
       2016-09-02 15:21:35 +08:00
    为了拼 sql 的时候方便一点,不用判断是否为第一个条件。
    后面的条件,直接加 and 就可以了
    hubertZheng
        22
    hubertZheng  
       2016-09-02 15:25:59 +08:00
    同拼接 sql
    caixiexin
        23
    caixiexin  
       2016-09-02 15:30:27 +08:00
    @Infernalzero 讲真,现在用 mybatis 有时候还会这么写 = =|| ,对 orm 老是有种本能的排斥
    caixiexin
        24
    caixiexin  
       2016-09-02 15:31:44 +08:00
    @yueyoum 为什么会 low 呢,某些场景下这么写可读性挺好的,也没有性能问题= =
    FrankFang128
        25
    FrankFang128  
       2016-09-02 15:33:22 +08:00 via Android
    少一个 if
    zuotech
        27
    zuotech  
       2016-09-02 15:37:45 +08:00
    一般用于条件的拼接, 在 mysql 里可以写成 where 1 , oracle 才需要 where 1=1 这么 low 的写法...哈哈
    riverphoenix
        28
    riverphoenix  
       2016-09-02 15:44:02 +08:00   ❤️ 2
    当初公司的 orm 也是这么写的,然后就被人注入了
    dong3580
        29
    dong3580  
       2016-09-02 15:44:58 +08:00
    @zuotech
    MSSQL 也是 where 1=1 ,顺便问一下,哪儿 low 了?
    zuotech
        30
    zuotech  
       2016-09-02 16:00:29 +08:00
    @dong3580 开个玩笑, 因为非要写个表达式 , 如果别人写个 where 123 = 123 ,你说行不行, 当然行, 就是感觉上很 low
    dong3580
        31
    dong3580  
       2016-09-02 16:01:26 +08:00
    @zuotech
    哈哈,笑点一下变低了。。。
    jy01264313
        32
    jy01264313  
       2016-09-02 17:01:54 +08:00
    完全有点不知所措
    mfu
        33
    mfu  
       2016-09-02 17:16:42 +08:00
    一般直接写个 where 1 and XXX...
    yueyoum
        34
    yueyoum  
       2016-09-02 17:20:27 +08:00
    @caixiexin

    别总是把性能挂在嘴上, 我说 low 指的是 拼接完全不需要 where 1 = 1 啊, 这样 LZ 就不会有这样的疑问了
    wyntergreg
        35
    wyntergreg  
       2016-09-02 17:20:50 +08:00
    @yueyoum 有的企业级报表的一条 sql 就 100 多行,各种联表各种嵌套,你不懒你 orm 搞一搞。你不 low 你搞一种比拼接字符串或者字符串匹配效率更高的方式出来。
    gdtv
        36
    gdtv  
       2016-09-02 17:21:45 +08:00
    @riverphoenix 这个写法和注入没有任何关系
    yueyoum
        37
    yueyoum  
       2016-09-02 17:21:50 +08:00
    @linescape ORM 确实在 处理复杂查询, 写出来的 代码 比 raw sql 还要复杂。

    ORM 为啥 拼接的 SQL 就没有 where 1 =1 这种蛋疼的东西? 你想想
    yueyoum
        38
    yueyoum  
       2016-09-02 17:22:26 +08:00
    @wyntergreg 见 LS
    wyntergreg
        39
    wyntergreg  
       2016-09-02 17:22:47 +08:00
    @yueyoum oracle 你不写 1=1 你试试
    zhs227
        40
    zhs227  
       2016-09-02 17:22:56 +08:00
    很早很早以前,在某些数据库使用不带条件的 delete 时不会返回删除记录数,就会有人给加上一个 where 1=1 ,这样会返回 affected rows 。至于 select 中的 1=1 的话,应该就是纯粹的方便串拼接吧
    wyntergreg
        41
    wyntergreg  
       2016-09-02 17:24:28 +08:00
    @yueyoum orm 浪费性能加了个判断,把拼好的条件的第一个 and 给 replace 了。用 1=1 的方式性能绝无问题
    Ixizi
        42
    Ixizi  
       2016-09-02 17:25:20 +08:00
    没有 ORM 不会用数据库
    wyntergreg
        43
    wyntergreg  
       2016-09-02 17:27:15 +08:00
    @Ixizi orm 用到最后会发现不会写 sql 了。而且复杂的 sql 用 orm 是做不到的
    tjxjj
        44
    tjxjj  
       2016-09-02 17:28:01 +08:00
    编程技巧而已。
    linescape
        45
    linescape  
       2016-09-02 17:32:20 +08:00
    @riverphoenix 拼接无问题,做好变量绑定
    yueyoum
        46
    yueyoum  
       2016-09-02 17:50:16 +08:00
    @wyntergreg

    我知道你的意思, 就是 添加一个新 条件, 就往老条件后面 + " and " + 新条件
    最后还要把 最前面的 and 去掉。

    如果要判断 还有性能损失。


    1 , 在操作数据库, 有大量 IO 的情况下, 判断一个 空字符串 也能给你的程序 带来 性能担忧, 那也就不用讨论了, 我还没达到你的高度

    2 , 就算不判断, 也可以直接拼接 两个 API 罢了。 一个 初始化条件, 一个 append 其他条件



    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void append_the_fucking_condition(char* conditon, const char* other)
    {
    strcat(conditon, " and ");
    strcat(conditon, other);
    }

    char* make_condition(const char* first_condition)
    {
    char* conditon = (char*)malloc(sizeof(char) * 512);
    strcat(conditon, first_condition);
    return conditon;
    }



    int main()
    {
    char* conditon = make_condition("o.operation_time>=\'2016/6/1\'");
    append_the_fucking_condition(conditon, "o.operation_time<\'2016/7/28\'");

    printf("%s\n", conditon);

    free(conditon);
    return 0;
    }
    plan9
        47
    plan9  
       2016-09-02 20:51:49 +08:00
    @yueyoum 程序有 bug😓
    barbery
        48
    barbery  
       2016-09-02 21:38:12 +08:00
    这种 SQL ,我也醉了
    shinwood
        49
    shinwood  
       2016-09-02 21:38:29 +08:00
    用 1 AND 不是更方便。

    这样写还有一种原因,为了 debug 起来方便。
    alexapollo
        50
    alexapollo  
       2016-09-02 21:40:16 +08:00
    Python 大法好
    ykrl089
        51
    ykrl089  
       2016-09-02 21:42:06 +08:00
    拼接 sql 很容易出问题的,竟然还有人敢这么干!
    SoloCompany
        52
    SoloCompany  
       2016-09-03 00:26:08 +08:00   ❤️ 3
    从这么多回复看来很多人要么是强迫症或者自我感觉太良,要么从来没有维护过数据库
    事实上 1=1 已经几乎可以说成为了一种约定

    如果需要我要手写一个复杂一些的 SQL 语句,习惯上也都会在编辑器里面的条件前面加一个 1=1 然后回车,然后每个 AND 条件写一行,最后加上分号

    好处是什么呢?
    你后面继续写下面的 AND 条件根本无需担心关键字和顺序
    你可以随便交换两个 AND 条件(可能仅仅是为了更好看)
    可以随便复制粘贴一行条件到其它位置再修改
    可以随便删除一行条件包括第一个而不需要手工修正任何内容

    再举另一个例子
    java 或者 js 的数组都允许最后一个元素悬挂一个逗号
    目的也是为了可以让多行元素来定义数组的时候,能够保持对称性,去除首尾效应
    美观有时候并不是这么重要
    so898
        53
    so898  
       2016-09-03 00:38:28 +08:00   ❤️ 4
    我要是告诉你们还有 WHERE 1=2 OR 这种技巧,楼上几个有洁癖的是不是要炸
    ivvei
        54
    ivvei  
       2016-09-03 03:00:50 +08:00
    我写 SQL 一般是这样写的:

    select a
    ,b
    ,c
    ,d
    from tble
    where 1=1
    and xxxxx
    and xxxxx

    逗号都写前面,方便调试。

    如果是程序里拼接,加判断当然可以。但是既然可以不加判断直接写,为什么非要多写个判断呢?
    mgcnrx11
        55
    mgcnrx11  
       2016-09-03 06:07:01 +08:00 via iPhone
    我说一个碰到的问题。项目使用 druid 做数据库连接池,自带某安全功能会校验永真条件,只要出现永真条件就不会让 SQL 跑,目的猜是为了防 SQL 注入,一般的 SQL 注入手法之一。然后问题来了, 1=1 就是一个永真条件……从安全觉度再讨论,是否不应该去建议这样拼 SQL 呢
    blacklee
        56
    blacklee  
       2016-09-03 06:40:43 +08:00
    按楼上很多人的说法,这样拼 sql 我用了 10 来年了,怎么就没出过问题呢?这是个问题。

    我看是你们满眼觉得 1=1 是何等的不爽,而忽略了更为重要的事情。这才是问题。
    iyangyuan
        57
    iyangyuan  
       2016-09-03 07:40:09 +08:00 via iPhone
    造成 sql 注入的根本原因是用户输入参数未转义,和 1=1 有什么关系?关键在于不要直接拼接参数,而是将其用占位符表示。难道 ORM 底层的 sql 不是拼接出来的吗?
    caixiexin
        58
    caixiexin  
       2016-09-03 08:41:14 +08:00 via Android
    @ykrl089 拼接 SQL ,然后参数转义并 Prepared Statements 化就没问题。
    Fedor
        59
    Fedor  
       2016-09-03 08:51:21 +08:00
    我一般
    WHERE 1
    AND ....
    AND ....
    AND ....
    AND ....
    ytmsdy
        60
    ytmsdy  
       2016-09-03 08:53:27 +08:00
    @SoloCompany 同意。。
    wbing
        61
    wbing  
       2016-09-03 09:22:19 +08:00 via Android
    原来还有这种方式, get 到了
    badcode
        62
    badcode  
       2016-09-03 09:22:38 +08:00
    有一种场景
    删表中全数据的时候
    DELETE FROM `table` WHERE 1=1
    ykrl089
        63
    ykrl089  
       2016-09-03 10:14:41 +08:00 via iPhone
    @caixiexin 问题是很多人拼着拼着就忘了,或者换个人开发不定按套路来。所以还是 orm 安全点
    516654246
        64
    516654246  
       2016-09-03 10:21:09 +08:00
    查询时偶尔也会这样写。为了调试...
    select xx from table where
    a=x?
    and b=y?
    我如果调试不要过滤条件是不是把 2 、 3 行干掉还得去把 where 删掉?
    我如果加了 1=1...
    至于性能...?和强迫症
    blacklee
        65
    blacklee  
       2016-09-03 11:30:55 +08:00
    一起写 Java 的时候经常这么干,并没有什么不好的。
    现在自己写 Rails 就不需要这么干了

    ``
    <code>
    @topics = Topic.all
    if params[:name] && !params[:name].empty?
    @topics = @topics.where("title like ?", "%#{params[:name]}%")
    end
    if params[:id] && !params[:id].empty?
    @topics = @topics.where("id = ?", "#{params[:id]}")
    end
    if params[:status] && !params[:status].empty?
    @topics = @topics.where("status = ?", params[:status])
    end
    </code>
    ``

    顺便看看 V2 的编辑器能不能搞代码
    tabris17
        66
    tabris17  
       2016-09-03 13:48:09 +08:00 via iPhone
    复杂的 sql 虽然用的少,但是绝对是必要的,一般会写个自动拼接 sql 的助手类,可以避免注入
    mind3x
        67
    mind3x  
       2016-09-03 20:47:48 +08:00 via Android
    楼上写 Java 的各位,即使不用 ORM ,还有个东西叫 jOOQ
    conglovely
        68
    conglovely  
       2016-09-04 00:12:08 +08:00
    经常用 plsql ,写 1=1 美化后, and 在下一行,方便注释。。。
    dungeonsnd
        69
    dungeonsnd  
       2016-09-04 09:45:33 +08:00
    大家都在用 ORM 吗?
    如果有些平台或者库没有特别好的怎么办? 比如 iOS 平台,我不想用 CoreData ,想用 fmdb 。那怎么用 ORM? 自己开发一套 ORM?
    fortunezhang
        70
    fortunezhang  
       2016-09-04 11:29:51 +08:00
    为以后用填坑呢.如果哪天想要添加条件直接在 1=1 后面写,或者替换 1=1 就可以了
    ETO
        71
    ETO  
       2016-09-05 09:03:15 +08:00
    @yueyoum 不能赞同。:)
    wilddog
        72
    wilddog  
       2016-09-05 09:23:26 +08:00
    是为了拼接 sql !
    lbp0200
        73
    lbp0200  
       2016-09-05 11:06:14 +08:00 via Android
    SQL 注入欢迎您
    initdrv
        74
    initdrv  
       2016-09-05 11:28:02 +08:00
    看似简单的问题,其实不简单啊,在下输了,只知道方便拼接条件,却没想到能涉及那么多方面的知识……
    Lucups
        75
    Lucups  
       2016-09-05 16:27:56 +08:00
    这种 where 1 = 1 的写法我几年前年第一次见到同事写时觉得有点 low ,但发现确实很实用。

    ORM 在 SQL 比较复杂的情况下确实比较乏力,所以有时候用这种方式快捷方便,也容易理解, ORM 写出来的代码可能更难理解。

    另外,这个用法跟 SQL Injection 有半毛钱关系?
    wmhx
        76
    wmhx  
       2016-09-05 16:30:33 +08:00
    1=1 和注入没关系, 只是为了拼接方便, 拼接当然是拼接有占位符的 sql, 以下是我用 jfinal 的示例:
    String sqlExceptSelect = " from t1 where 1=1 ";
    List < Object > paras = new ArrayList < Object > ( );
    if ( !"".equals ( pinfen1 ) ) {// /评分 start
    sqlExceptSelect += " and {pinfen}>=? ";
    paras.add ( pinfen1 );
    }
    if ( !"".equals ( pinfen2 ) ) {// /评分 end
    sqlExceptSelect += " and {pinfen} <=? ";
    paras.add ( pinfen2 );
    }
    sqlExceptSelect = sqlExceptSelect.replaceAll ( "\\{pinfen\\}" , "cast( `评分` as decimal(10,2))" )// /
    Page < Record > llpg = DB ( db ).paginate ( 1,20, "select * " , sqlExceptSelect , paras.toArray ( new Object [ paras.size ( ) ] ) );

    pinfen1 和 pinfen2 是界面输入的, 您看能注入么?
    dhssingle
        77
    dhssingle  
       2016-09-05 18:58:44 +08:00
    注入和 1=1 有毛关系
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3833 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 10:34 · PVG 18:34 · LAX 02:34 · JFK 05:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.