解释下面描述的存储过程

时间:2018-07-04 11:44:17

标签: mysql stored-procedures

CREATE DEFINER=`root`@`localhost` PROCEDURE `get_plan_images`(
    _list varchar(2000)
)
BEGIN
   SET @LIST=_list;
   set @sql = concat('SELECT plan_id, plan_image 
                        FROM ibuild.plan_images 
                       where plan_id in (', @LIST , ')');
   PREPARE q FROM @sql;
   execute q;
END

concat在这里做什么?这句话的意思是PREPARE q FROM @sql;

1 个答案:

答案 0 :(得分:0)

CONCAT只是将两个或多个文本合并在一起。在上面的示例中,@ LIST包含传递给过程的ID列表。在CONCAT之后,@ sql变成包含以下内容的字符串:#include <tuple> #include <vector> #include <algorithm> template<class T> using prtVector = std::vector<T*>; // Interface, as required by assignment class BaseObject { public: virtual ~BaseObject() {} virtual prtVector<BaseObject> getAllParents() const = 0; virtual prtVector<BaseObject> getAllChildren() const = 0; virtual void removeAllParents() = 0; virtual void removeAllChildren() = 0; }; // base prototype template<typename TOwnTag, typename TParentTagsTuple, typename TChildTagsTuple> class Obj; // Parent-type deduction template<typename TOwnTag, typename TParentTag, typename... TParentTags, typename... TChildTags> class Obj<TOwnTag, std::tuple<TParentTag, TParentTags...>, std::tuple<TChildTags...>> : public Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>> { // local types using TOwn = typename TOwnTag::obj_type; using TParent = typename TParentTag::obj_type; // container prtVector<TParent> parentsPtrs; //befriend types friend class Obj; template<class A, class B> friend void addRelation(A* const a, B* const b); protected: // prevent base function hiding with 'using'-declaration using Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>>::addParent; using Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>>::removeParent; // add and remove element functions void addParent(TParent* const parentPtr) { parentsPtrs.push_back(parentPtr); } void removeParent(TParent const* const parentPtr) { auto it = std::find(std::cbegin(parentsPtrs), std::cend(parentsPtrs), parentPtr); if (it != std::cend(parentsPtrs)) parentsPtrs.erase(it); } public: virtual ~Obj() {} virtual prtVector<BaseObject> getAllParents() const override { auto result = Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>>::getAllParents(); result.insert(std::begin(result), std::cbegin(parentsPtrs), std::cend(parentsPtrs)); return result; } virtual prtVector<BaseObject> getAllChildren() const override { return Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>>::getAllChildren(); } virtual void removeAllParents() override { Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>>::removeAllParents(); for (auto&& parent : parentsPtrs) parent->removeChild(reinterpret_cast<TOwn* const>(this)); } virtual void removeAllChildren() override { Obj<TOwnTag, std::tuple<TParentTags...>, std::tuple<TChildTags...>>::removeAllChildren(); } }; // Child-type deduction template<typename TOwnTag, typename TChildTag, typename... TChildTags> class Obj<TOwnTag, std::tuple<>, std::tuple<TChildTag, TChildTags...>> : public Obj<TOwnTag, std::tuple<>, std::tuple<TChildTags...>> { // local types using TOwn = typename TOwnTag::obj_type; using TChild = typename TChildTag::obj_type; // container prtVector<TChild> childrenPtrs; //befriend types friend class Obj; template<class A, class B> friend void addRelation(A* const a, B* const b); protected: // empty functions required for 'using'-declaration void addParent() {} void removeParent() {} // prevent base function hiding with 'using'-declaration using Obj<TOwnTag, std::tuple<>, std::tuple<TChildTags...>>::addChild; using Obj<TOwnTag, std::tuple<>, std::tuple<TChildTags...>>::removeChild; // add and remove element functions void addChild(TChild* const childPtr) { childrenPtrs.push_back(childPtr); } void removeChild(TChild const* const childPtr) { auto it = std::find(std::cbegin(childrenPtrs), std::cend(childrenPtrs), childPtr); if (it != std::cend(childrenPtrs)) childrenPtrs.erase(it); } public: virtual ~Obj() {} virtual prtVector<BaseObject> getAllParents() const override { return Obj<TOwnTag, std::tuple<>, std::tuple<TChildTags...>>::getAllParents(); } virtual prtVector<BaseObject> getAllChildren() const override { auto result = Obj<TOwnTag, std::tuple<>, std::tuple<TChildTags...>>::getAllChildren(); result.insert(std::begin(result), std::cbegin(childrenPtrs), std::cend(childrenPtrs)); return result; } virtual void removeAllParents() override {} virtual void removeAllChildren() override { Obj<TOwnTag, std::tuple<>, std::tuple<TChildTags...>>::removeAllChildren(); for (auto&& child : childrenPtrs) child->removeParent(reinterpret_cast<TOwn* const>(this)); } }; // terminator template<typename TOwnTag> class Obj<TOwnTag, std::tuple<>, std::tuple<>> : public BaseObject { protected: // empty functions required for 'using'-declaration void addChild() {} void removeChild() {} void addParent() {} void removeParent() {} public: virtual ~Obj() {} virtual prtVector<BaseObject> getAllParents() const override { return prtVector<BaseObject>(); } virtual prtVector<BaseObject> getAllChildren() const override { return prtVector<BaseObject>(); } virtual void removeAllParents() override {} virtual void removeAllChildren() override {} }; //prototype class tags struct Human_tag; struct Tree_tag; struct Dog_tag; struct Parasite_tag; //define class types using Human = Obj<Human_tag, std::tuple<>, std::tuple<Tree_tag, Dog_tag>>; using Tree = Obj<Tree_tag, std::tuple<Human_tag>, std::tuple<>>; using Dog = Obj<Dog_tag, std::tuple<Human_tag>, std::tuple<Parasite_tag>>; using Parasite = Obj<Parasite_tag, std::tuple<Dog_tag>, std::tuple<>>; //couple tags to classes struct Human_tag { using obj_type = Human; }; struct Tree_tag { using obj_type = Tree; }; struct Dog_tag { using obj_type = Dog; }; struct Parasite_tag { using obj_type = Parasite; }; //(befriend)helper function // maybe could do somehting with std::enable_if // i.e. "enable if type B is in child tuple of A and // type A is in parent tuple of B" // that way the parser will already detect a relation is not possible template<class A, class B> void addRelation(A* const a, B* const b) { a->addChild(b); b->addParent(a); } // now for some testing #include <iostream> int main() { Human h1; Dog d1, d2; Parasite p1; addRelation(&h1, &d1); addRelation(&h1, &d2); addRelation(&d1, &p1); //addRelation(&h1, &p1); // compiler error auto result = h1.getAllChildren(); std::cout << result.size() << "\n"; //print 2 d1.removeAllParents(); result = h1.getAllChildren(); std::cout << result.size() << "\n"; //print 1 std::cin.ignore(); }

参见此处:MySQL CONCAT Function

PREPARE语句只是给该语句起一个名字,以便您可以执行它。看到这里:MySQL PREPARE